I have an array with fields
[
"house" => "30|30|30",
"street" => "first|second|third",
...
]
I want to get array
[
[
"house" => "30",
"street" => "first",
...
],
[
"house" => "30",
"street" => "second",
...
],
[
"house" => "30",
"street" => "third",
...
]
]
I know how I can solve this using PHP and loop, but maybe this problem has more beautiful solution
use zip
$data = [
"house" => "30|30|30",
"street" => "first|second|third",
];
$house = collect(explode('|',$data['house']));
$street = collect(explode('|',$data['street']));
$out = $house->zip($street);
$out->toarray();
Here's something I managed to do with tinker.
$original = [
"house" => "30|30|30",
"street" => "first|second|third",
];
$new = []; // technically not needed. data_set will instantiate the variable if it doesn't exist.
foreach ($original as $field => $values) {
foreach (explode('|', $values) as $index => $value) {
data_set($new, "$index.$field", $value);
}
}
/* dump($new)
[
[
"house" => "30",
"street" => "first",
],
[
"house" => "30",
"street" => "second",
],
[
"house" => "30",
"street" => "third",
],
]
*/
I tried using collections, but the main problem is the original array's length is not equal to the resulting array's length, so map operations don't really work. I suppose you can still use each though.
$new = []; // Since $new is used inside a Closure, it must be declared.
collect([
"house" => "30|30|30",
"street" => "first|second|third",
...
])
->map(fn($i) => collect(explode('|', $i))
->each(function ($values, $field) use (&$new) {
$values->each(function ($value, $index) use ($field, &$new) {
data_set($new, "$index.$field", $value);
});
});
$array = ["house" => "30|30|30","street" => "first |second| third"];
foreach($array as $key=> $values){
$explodeval = explode('|',$values);
for($i=0; $i<count($explodeval); $i++){
$newarray[$i][$key]= $explodeval[$i];
}
}
output:
Array
(
[0] => Array
(
[house] => 30
[street] => first
)
[1] => Array
(
[house] => 30
[street] => second
)
[2] => Array
(
[house] => 30
[street] => third
)
)
Related
How is it possible to pick a random value with PHP from an Array?
Example:
$trees = [
"appletree" => [
"id" => "12378",
"age" => [15],
"height" => [6]
],
"bananatree" => [
"id" => "344343453",
"age" => [16],
"height" => [30]
],
"peachtree" => [
"id" => "34534543",
"age" => [35],
"height" => [4]
];
How would I access one of the id's randomly?
I tried using
$tree_id = array_rand($trees['id']);
echo $tree_id;
echo "\r\n";
but I'm slowly hitting a wall of understanding.
array_rand() returns a random array key. So give it the $trees array to get a tree name, then use that to index the array and access its id property.
$random_tree = array_rand($trees);
echo $trees[$random_tree]['id'];
maybe this function I created can help:
<?php
$trees = [
"appletree" => [
"id" => "123",
"age" => [15],
"height" => [6]
],
"bananatree" => [
"id" => "456",
"age" => [16],
"height" => [30]
],
"peachtree" => [
"id" => "789",
"age" => [35],
"height" => [4]
] // <- you were missing this bracket
];
function pickRand($array){
// Create Temp array
$temparray = [];
// Iterate through all ID's and put them into out temp array
foreach($array as $a) $temparray[] = $a['id'];
// Get a random number out of the number of ID's we have
$rand = rand(0, count($temparray) - 1);
// Return Result
return $temparray[$rand];
}
// Use Function
echo pickRand($trees);
Live Demo: http://sandbox.onlinephpfunctions.com/code/e71dc6b07c3ec93051c69adc66b28aafe555a104
i have 1 array like below :
0 => array:4 [
"id" => "1"
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
]
1 => array:4 [
"id" => "2"
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
]
now what i want to do ?? as you can see the date and from_time and to_time have the same value . i want to merge them to 1 item like below :
0 => array:4[
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
"id" => ["1" , "2"]
].
so i can have the same day ids in 1 index of array and if for example the same date and time got 4 ids i get the id key with 4ids . i used array_merge_recursive but it didnt help me with the same keys of an array
this is how i am building the array :
foreach ($arrays as $key => $array) {
$options[$key]['id'] = last(str_split($array['id']));
$options[$key]['date'] = substr($array['id'],0,-2);
$options[$key]['from_time'] = Carbon::createFromTimestamp($array['pickup']['from'])->format('H');
$options[$key]['to_time'] = Carbon::createFromTimestamp($array['pickup']['to'])->format('H');
}
. thanks in advance for help
<?php
//define items
$items = [
[
"id" => "1",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14",
],[
"id" => "2",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14",
]
];
$options = [];
//loop through the items
foreach ($items as $item) {
//set up the hashing key to use to locate if we hit dup entry
$key = "{$item['date']}-{$item['from_time']}-{$item['to_time']}";
//if indexing key not in options = never looked at it before
if (!array_key_exists($key, $options)) {
//have the key points to the current entry
$options[$key] = $item; //attach the whole item to it
//we want the id to be an array to initialize it to be one
$options[$key]['id'] = [];
}
//gets here then we know options[$key] exists
//if the item id not in the id array of our dict
if (!in_array($item['id'], $options[$key]['id'])) {
//add to it
$options[$key]['id'][] = $item['id'];
}
}
//array_values to get the values and not worry about the keys
print_r(array_values($options));
You can do something like this:
$arr = [
[
"id" => "1",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14"
],
[
"id" => "2",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14"
],
[
"id" => "3",
"date" => "2021-08-03",
"from_time" => "14",
"to_time" => "16"
]
];
$res = array_reduce($arr, function($carry, $entry) use(&$arr) {
$matches = array_filter($arr, function($item) use($entry) {
return $item['from_time'] === $entry['from_time'] && $item['to_time'] && $entry['to_time'];
});
//print_r([ $entry['id'], $matches ]);
foreach($matches as $match) {
unset($arr[array_search($match['id'], array_column($matches, 'id'))]);
}
if (!count($matches)) {
return $carry;
}
$carry[] = [
'id' => array_column($matches, 'id'),
'date' => $entry['date'],
'from_time' => $entry['from_time'],
'to_time' => $entry['to_time'],
];
return $carry;
}, []);
This question already has answers here:
How to access and manipulate multi-dimensional array by key names / path?
(10 answers)
Closed 2 years ago.
I'm trying to get reach a point in a dynamicly generated multidimensional array based on a array with keys.
Basicly I have the following array:
$arr = [
"something" => [
'something_else' => [
"another_thing" => "boo"
]
],
"something2" => [
'something_elseghf' => [
"another_thingfg" => [
"hi" => "bye"
]
]
],
"info" => [
'something_else2' => [
"another_thingh" => "boo"
]
],
];
Now I want to set a value in the array based on the keys in a different array:
$keyArr = ["something2", 'something_elseghf' "another_thingfg", "hi"];
So the above array means that I need to set the hi key to some value. How can I reach that part of the array with these random keys, note that the length of $keyArr is dynamic aswell. So I can't reach it with:
$arr[$keyArr[0]][$keyArr[1]][$keyArr[2]][$keyArr[3]] =
Hope anyone has an idea on how to solve this!
Try this approach:
$arr = [
"something" => [
'something_else' => [
"another_thing" => "boo"
]
],
"something2" => [
'something_elseghf' => [
"another_thingfg" => [
"hi" => "bye"
]
]
],
"info" => [
'something_else2' => [
"another_thingh" => "boo"
]
],
];
$keyArr = ["something2", 'something_elseghf', "another_thingfg", "hi"];
$cursor = $arr;
foreach ($keyArr as $key) {
$cursor = $cursor[$key];
}
echo $cursor;
Will echo
bye
UPDATE:
If you want to change a value within multi-dimentional array, then use a recursive function, like this:
function changeValue($array, $path, $value) {
if (empty($path)) {
return $value;
}
$key = array_shift($path);
$array[$key] = changeValue($array[$key], $path, $value);
return $array;
}
$arr = [
"something" => [
'something_else' => [
"another_thing" => "boo"
]
],
"something2" => [
'something_elseghf' => [
"another_thingfg" => [
"hi" => "bye"
]
]
],
"info" => [
'something_else2' => [
"another_thingh" => "boo"
]
],
];
$keyArr = ["something2", 'something_elseghf', "another_thingfg", "hi"];
$changedArray = changeValue($arr, $keyArr, 'New value!');
print_r($changedArray);
Will output
Array
(
[something] => Array
(
[something_else] => Array
(
[another_thing] => boo
)
)
[something2] => Array
(
[something_elseghf] => Array
(
[another_thingfg] => Array
(
[hi] => New value!
)
)
)
[info] => Array
(
[something_else2] => Array
(
[another_thingh] => boo
)
)
)
I have the following array:
$arr = [
"elem-1" => [ "title" => "1", "desc" = > "" ],
"elem-2" => [ "title" => "2", "desc" = > "" ],
"elem-3" => [ "title" => "3", "desc" = > "" ],
"elem-4" => [ "title" => "4", "desc" = > "" ],
]
First I need to change the value from [ "title" => "1", "desc" = > "" ] to 1 (title's value).
I did this using array_walk:
array_walk($arr, function(&$value, $key) {
$value = $value["title"];
});
This will replace my value correctly. Our current array now is:
$arr = [
"elem-1" => "1",
"elem-2" => "2",
"elem-3" => "3",
"elem-4" => "4",
]
Now, I need to transform each element of this array into its own subarray. I have no idea on how to do this without a for loop. This is the desired result:
$arr = [
[ "elem-1" => "1" ],
[ "elem-2" => "2" ],
[ "elem-3" => "3" ],
[ "elem-4" => "4" ],
]
You can change your array_walk callback to produce that array.
array_walk($arr, function(&$value, $key) {
$value = [$key => $value["title"]];
});
Run the transformed array through array_values if you need to get rid of the string keys.
$arr = array_values($arr);
To offer an alternative solution you could achieve all of this with array_map
<?php
$arr = [
"elem-1" => [ "title" => "1", "desc" => "" ],
"elem-2" => [ "title" => "2", "desc" => "" ],
"elem-3" => [ "title" => "3", "desc" => "" ],
"elem-4" => [ "title" => "4", "desc" => "" ],
];
function convertToArray($key,$elem){
return [$key => $elem['title']];
}
$arr = array_map("convertToArray", array_keys($arr), $arr);
echo '<pre>';
print_r($arr);
echo '</pre>';
?>
outputs
Array
(
[0] => Array
(
[elem-1] => 1
)
[1] => Array
(
[elem-2] => 2
)
[2] => Array
(
[elem-3] => 3
)
[3] => Array
(
[elem-4] => 4
)
)
It doesn't make much sense to use array_walk() and modify by reference because the final result needs to have completely new keys on both levels. In other words, the output structure is completely different from the input and there are no salvageable/mutable parts. Mopping up the modified array with array_values() only adds to the time complexity cost.
array_map() has to bear a cost to time complexity too because array_keys() must be passed in as an additional parameter.
If you want to use array_walk(), use use() to modify the result array. This will allow you to enjoy the lowest possible time complexity.
More concise than array_walk() and cleaner to read, I would probably use a classic foreach() in my own project.
Codes: (Demo)
$result = [];
array_walk(
$arr,
function($row, $key) use(&$result) {
$result[] = [$key => $row['title']];
}
);
Or:
$result = [];
foreach ($arr as $key => $row) {
$result[] = [$key => $row['title']];
}
var_export($result);
You need to use array_map like
$new_arr= array_map(function($key,$val){
return [$key => $val['title']];},array_keys($arr),$arr);
I have an array that looks like this
"name" => array:3 [
1 => "Hello"
4 => "Test"
21 => "Test2"
]
"runkm" => array:3 [
1 => "100.00"
4 => "1000.00"
21 => "2000.00"
]
"active" => array:3 [
1 => "1"
4 => "0"
21 => "0"
]
Can i somehow combine the matching keys with a PHP function so that the array would look like this instead
1 => array:3 [
name => "Hello"
runkm => "100.00"
active => "1"
]
4 => array:3 [
name => "Test"
runkm => "1000.00"
active => "0"
]
21 => array:3 [
name => "Test2"
runkm => "2000.00"
active => "0"
]
EDIT: Thanks for all the answers guys. What i was really looking for was a PHP built in function for this, which i probably should have been more clear about.
$newArr=array();
foreach($array1 as $key => $value){
$newArr[$key]=>array(
'name' =>$value[$key];
'runkm' =>$array2[$key];
'active'=>$array3[$key];
);
}
this is how you make a new array and then print the $newArr and check you get what you want or not? Good Luck!
<?php
$resultarr = array();
for($i=0;$i<count($sourcearr['name']);$i++) {
$resultarr[] = array('name'=>$sourcearr['name'][$i], 'runkm'=>$sourcearr['runkm'][$i], 'active'=>$sourcearr['active'][$i]);
}
This works well. And also, doesn't use hard coded keys.
<?php
$arr = [
"name" => [
1 => "Hello",
4 => "Test",
21 => "Test2"
],
"runkm" => [
1 => "100.00",
4 => "1000.00",
21 => "2000.00"
],
"active" => [
1 => "1",
4 => "0",
21 => "0"
]
];
// Pass the array to this function
function extractData($arr){
$newarr = array();
foreach ($arr as $key => $value) {
foreach($value as $k => $v) {
if(!isset($newarr[$k]))
$newarr[$k] = array();
$newarr[$k][$key] = $v;
}
}
return $newarr;
}
print_r(extractData($arr));
?>
I'm not sure if there's a function that does that in PHP but maybe you can try this
$arr1 = array(
"name" => array(
1 => "hello",
4 => "test",
21 => "test2",
),
"runKm" => array(
1 => "100",
4 => "200",
21 => "300",
),
"active" => array(
1 => "1",
4 => "0",
21 => "0",
),
);
// declare another that will hold the new structure of the array
$nArr = array();
foreach($arr1 as $key => $val) {
foreach($val as $sub_key => $sub_val) {
$nArr[$sub_key][$key] = $sub_val;
}
}
what this does is simply loop thru each array and its values and assign it to another array which is the $nArr. I hope it helps.