How do I convert an 'N' elements single dimensional array to 'N' level nested array in PHP ?
Example:
Input:
$input = array('Orange','Apple','Banana');
Expected Output:
$output = array(
'name' => 'Banana',
'sub_category' => array(
'name' => 'Apple',
'sub_category' => array(
'name' => 'Orange'
);
This is my code:
$categories = array('Orange','Apple','Banana');
$count = count($categories);
for($i=0;$i<=$count;$i++){
if(isset($categories[$i+1])){
$parent = $categories[$i+1]; // parent
$categories[$i+1]=array(
'name' => $categories[$i+1],
'sub_category' => array('name' => $categories[$i])
);
}
}
$categories = $categories[$count-1];
var_dump($categories);
My code is sloppy and I also get the following incorrect output:
$output = array(
'name' => 'Banana',
'sub_category' => array(
'name' => array(
'name' => 'Apple',
'sub_category' => array(
'name' => 'Orange'
);
);
Edit 1:
The problem/solution provided here does not seem to be answering my question.
You could use simple recursion technique:
function toNestedArray(array $input, array $result = [])
{
$result = ['name' => array_pop($input)];
if (count($input)) {
$result['sub_category'] = toNestedArray($input, $result);
}
return $result;
}
$categories = array('Orange','Apple','Banana');
$count = count($categories);
$categories2=array();
for($i=$count-1;$i>0;$i--){
if($i-2>-1){
$categories2=array(
'name'=>$categories[$i],
'sub_category'=>array('name'=>$categories[$i-1],'sub_categories'=>array('name'=>$categories[$i-2]))
);
}
}
echo "<pre>";
print_r($categories2);
echo "</pre>";
A simple option is to loop over the $input array, building the $output array from inside to out.
$output = array();
foreach ($input as $name) {
if (empty($output)) {
$output = array("name" => $name);
} else {
$output = array("name" => $name, "sub_category" => $output);
}
}
Related
I have an array as
$apps = array(
array(
'id' => '2',
'name' => 'Popcorn'
),
array(
'id' => '1',
'name' => 'EveryCord'
),
array(
'id' => '2',
'name' => 'AirShou'
),
Here I want to print names where id="2". So I tried it with following code.
foreach ( $apps as $var ) if ($var['id'] == "2") {
echo $var['name']
}
The problem is that it only print first result of the array as
"Popcorn".
But I want to extract all result which are
"Popcorn and Airshou"
How can I fix this. Can someone help me !
Try this;
$apps = [
['name' => 'Fish', 'id' => 2],
['name' => 'Chips', 'id' => 1],
['name' => 'Sticks', 'id' => 2],
];
$using = [];
foreach ( $apps as $var ) {
if ($var['id'] == "2") {
$using[] = $var['name'];
}
}
echo implode(" and ", $using);
RESULT:
You can create a sample array.
And append the name to it, if it is id=2
Code:
$apps = [
['id' => '2', 'name' => 'Popcorn'],
['id' => '1', 'name' => 'EveryCord'],
['id' => '2', 'name' => 'AirShou']
];
$names = [];
if (! empty($apps)) {
foreach ($apps as $elem) {
if ($elem['id'] == 2) {
$names[] = $elem['name'];
}
}
}
$finalName = ! empty($names) ? implode(' and ', $names) : '';
echo '<pre>';print_r($finalName);echo '</pre>';
// Output: Popcorn and AirShou
You can filter the array on the item id and then retrieve the column name:
array_column(array_filter($apps, function($v){return '2' === $v['id'];}), 'name')
result:
array(2) {
[0] =>
string(7) "Popcorn"
[1] =>
string(7) "AirShou"
}
Change your loop by this code, and you will got both names,
foreach ( $apps as $var ){
if ($var['id'] == "2") {
echo $var['name'];
}
}
Just grab names in array then implode it like this:
$temp = array();
foreach ( $apps as $var ) if ($var['id'] == "2") {
$temp[] = $var['name']
}
echo implode(' and ', $temp);
My first array like this :
$photoList = array(
array(
'id' => 1,
'name' => 'chelsea.jpg'
),
array(
'id' => 2,
'name' => 'mu.jpg'
),
array(
'id' => 3,
'name' => 'city.jpg'
)
);
My second array like this :
photo = array('cover1'=>'liverpool.jpg', 'cover2'=>'city.jpg');
My code like this :
$photo = array_filter($photo, function($item) use ($photoList) {
return in_array($item, array_column($photoList, 'name')) ;
});
if (empty($photo))
$photo=null;
If I run : echo '<pre>';print_r($photo);echo '</pre>';, the result like this :
Array
(
[cover2] => city.jpg
)
I want the result like this :
Array
(
[cover1] => city.jpg
)
So if there is no cover1, the cover2 changed to be cover1
How can I do it?
You could re-index the keys like this :
$photoList = array(
array(
'id' => 1,
'name' => 'chelsea.jpg'
),
array(
'id' => 2,
'name' => 'mu.jpg'
),
array(
'id' => 3,
'name' => 'city.jpg'
)
);
$photo = array('cover1'=>'liverpool.jpg', 'cover2'=>'city.jpg');
$photo = array_filter($photo, function($item) use ($photoList) {
return in_array($item, array_column($photoList, 'name')) ;
});
if (empty($photo)){
$photo = null;
} else {
$idx = 1 ;
foreach ($photo as $key => $value) {
unset($photo[$key]);
$photo['cover'.$idx++] = $value;
}
}
print_r($photo);
Outputs :
Array
(
[cover1] => city.jpg
)
I'm not sure about what you really need. Assuming you want to do that recursively, I hope this helps:
$label = 'cover';
$index = 1;
$a_keys = array_keys($photo);
$new_photo = [];
foreach($a_keys AS $k=>$v){
$new_photo[$label.$index] = $photo[$k];
$index++;
}
$photo = $new_photo;
It will rewrite your array with wanted naming style.
Basically I want to add a dynamic array inside of another array, here's my array :
$myarray = array(
'options' => array( ),
);
And here's the dynamic array :
$page = array(
array('id' => '1' ,'title'=>'Page1' ),
array('id' => '2' ,'title'=>'Page2' )
);
I want to $myarray to be like this :
$myarray = array(
'options' =>
array('1' => 'Page1' ,'2'=>'Page2' ),
);
Here's what I tried :
foreach ($page as $key => $value) {
$myarray['options'][]=array(
"".$value['id']."" =>"".$value['title'].""
);
}
Any help with this? Thanks.
Here's a codepad demo
$myarray = [];
foreach($page as $key => $value) {
$myarray['options'][$value['id']] = $value['title'];
}
Just try with:
$myarray['options'] = array_reduce($page, function($options, $item){
$options[$item['id']] = $item['title'];
return $options;
});
I have an array with keys that describe location in a multidimensional array like:
array(
'3728:baskets:4839:1' => 'apple',
'3728:baskets:4839:2' => 'orange',
'3728:baskets:4920:1' => 'cherry',
'3728:baskets:4920:2' => 'apple',
'9583:baskets:4729:1' => 'pear',
'9583:baskets:4729:2' => 'orange',
'9583:baskets:6827:1' => 'banana',
'9583:baskets:6827:2' => 'pineapple',
);
I would like to pass this array to a function that generates a multidimensional array based on the the pieces in the keys delimited by the ":". The resulting array should look like:
array(
3728 => array(
'baskets' => array(
4839 => array(
1 => 'apple',
2 => 'orange',
),
4920 => array(
1 => 'cherry',
2 => 'apple',
),
),
),
9583 => array(
'baskets' => array(
4729 => array(
1 => 'pear',
2 => 'orange',
),
6827 => array(
1 => 'banana',
2 => 'pineapple',
),
),
),
);
Any ideas?
function array_createmulti($arr) {
// The new multidimensional array we will return
$result = array();
// Process each item of the input array
foreach ($arr as $key => $value) {
// Store a reference to the root of the array
$current = &$result;
// Split up the current item's key into its pieces
$pieces = explode(':', $key);
// For all but the last piece of the key, create a new sub-array (if
// necessary), and update the $current variable to a reference of that
// sub-array
for ($i = 0; $i < count($pieces) - 1; $i++) {
$step = $pieces[$i];
if (!isset($current[$step])) {
$current[$step] = array();
}
$current = &$current[$step];
}
// Add the current value into the final nested sub-array
$current[$pieces[$i]] = $value;
}
// Return the result array
return $result;
}
It would be faster then previous answer:
function formatMyData($data)
{
$res = array();
foreach($data as $key => $value) {
list($a, $b, $c, $d) = explode(':', $key);
if (!isset($res[$a])) {
$res[$a] = array(
$b => array(
$c => array(
$d => $value
)
)
);
}
else if (!isset($res[$a][$b])) {
$res[$a][$b] = array(
$с => array(
$d => $value
)
);
}
else if (!isset($res[$a][$b][$c])) {
$res[$a][$b][$c] = array(
$d => $value
);
} else {
$res[$a][$b][$c][$d] = $value;
}
}
return $res;
}
See in action
I have two arrays
$Array_1 = array(
'ID_1' => 'Michael',
'ID_2' => 'Jerry',
'ID_3' => 'Tony',
'ID_4' => 'Roger',
);
$Array_2 = array(
'ID_1' => 'Chef',
'ID_2' => 'Mechanic',
'ID_3' => 'Cook',
'ID_4' => 'Dealer',
);
I wish to merge them on the ID column and have my final array be in this form
$employees = array(
array(
'name' => 'Jason',
'occupation' => 'Chef'
),
array(
'name' => 'Mike',
'occupation' => 'Mechanic'
),
...
);
I know I can array combine them like below:
$new_array = array_combine(array_values($Array_1), array_values($Array_2));
but how would I add the titles "Name": and "Occupation":
Can you try this,
$Employees = array();
foreach($Array_1 as $key=>$value):
$Employees['Employees'][] = array('Name'=>$value, 'Occupation'=>$Array_2[$key]);
endforeach;
echo "<pre>";
print_r($Employees);
echo "</pre>";
echo json_encode($Employees);
OP:
{"Employees":[{"Name":"Jason","Occupation":"Chef"}, {"Name":"Mike","Occupation":"Mechanic"}]}
i dont know how the array look. but you can try my two solution
First solution
$array1 = array("id" => array("id1", "id2", "id3"), "names" => array("name1", "name2", "name3"));
$array2 = array("id" => array("id1", "id2", "id3"), "occupation" => array("occupation1", "occupation2", "occupation3"));
$filter_array = array("employees" => array());
foreach ($array1["id"] as $index => $key) {
$employee = array();
$occupation = in_array($key, $array2["id"]) ? $array2["occupation"][$index] : false;
if ($occupation === false) {
continue;
}
$employee["name"] = $key;
$employee["occupation"] = $occupation;
array_push($filter_array["employees"], $employee);
}
echo "<pre>" . print_r($filter_array, true) . "</pre>";
Second Solution
$array1 = array("id1" => array("names" => "name1"), "id2" => array("names" => "name2"), "id3" => array("names" => "name3"));
$array2 = array("id1" => array("occupation" => "occupation1"), "id2" => array("occupation" => "occupation2"), "id3" => array("occupation" => "occupation3"));
$filter_array = array("employees" => array());
foreach ($array1 as $key => $value) {
$employee = array();
if (!isset($array2[$key])) {
continue;
}
$employee["name"] = $value["names"];
$employee["occupation"] = $array2[$key]["occupation"];
array_push($filter_array["employees"], $employee);
}
echo "<pre>" . print_r($filter_array, true) . "</pre>";
i hope my code can help.
you can try this
$Array_1 = array(
'ID_1' => 'Michael',
'ID_2' => 'Jerry',
'ID_3' => 'Tony',
'ID_4' => 'Roger',
);
$Array_2 = array(
'ID_1' => 'Chef',
'ID_2' => 'Mechanic',
'ID_3' => 'Cook',
'ID_4' => 'Dealer',
);
$filter_array = array("employees" => array());
foreach($Array_1 as $key => $value){
$employee = array();
if(!isset($Array_2[$key])){ continue; }
$employee["name"] = $value;
$employee["occupation"] = $Array_2[$key];
array_push($filter_array["employees"], $employee);
}
EDIT 2
Aah, now I see the phpfiddle in the comments and the edit to the OP. So, the ID is already the key of the array? ... Then just do
foreach($Array_1 as $key_1 => $value_1) {
$new_Array[$key_1]['Names'] = $Array_1['Names'];
}
foreach($Array_2 as $key_2 => $value_2) {
$new_Array[$key_2]['Occupation'] = $Array_2['Occupation'];
}
use array_walk . It runs a function per each array item .combine them in the function .