Reputation: 103
I want to create one n-level menu array from my php array. There can be n-level of children. The main array will be same means not a multidimensional n-level array. I've provided a sample array which meets the array structure I'm using.
$menu_array =
Array
(
[menu-main] => Array
(
[menu_name] => Menu Name 1
[menu_slug] => menu-main
[parent_menu_slug] =>
)
[menu-sub-main] => Array
(
[menu_name] => Sub Menu 1
[menu_slug] => menu-sub-main
[parent_menu_slug] => menu-main
)
[menu-sub-sub-main] => Array
(
[menu_name] => Sub Sub Menu 1
[menu_slug] => menu-sub-sub-main
[parent_menu_slug] => menu-sub-main
)
[menu-main1] => Array
(
[menu_name] => Menu Name 1
[menu_slug] => menu-main1
[parent_menu_slug] =>
)
)
I want to create the n-level array to generate the menu from this array. To do so, I tried below
$x = [];
$tmp = array_combine(array_column($menu_array,'menu_slug'), $menu_array);
//parent menus only
foreach ($tmp as $k => $t) {
if (empty($t['parent_menu_slug'])) {
$x[$t['menu_slug']] = $t;
unset($tmp[$k]);
}
}
$d = [];
$rec_fn = function ($temp,$parent_slug = '') use (&$rec_fn,$x,&$d) {
if ($parent_slug && array_key_exists($parent_slug,$x)) {
$d[$parent_slug]['children'][] = $temp;
} else {
foreach ($temp as $c) {
if (!empty($c['parent_menu_slug'])) {
$d['children'][] = $rec_fn($c,$c['parent_menu_slug']);
}
}
}
return $d;
};
$final_menu = $rec_fn($tmp);
But it is not returning the required result. The required result is
Array
(
[menu-main] => Array
(
[menu_name] => Menu Name 1
[menu_slug] => menu-main
[parent_menu_slug] =>
[children] => array(
[menu-sub-main] => Array
(
[menu_name] => Sub Menu 1
[menu_slug] => menu-sub-main
[parent_menu_slug] => menu-main
[children] => array(
[menu-sub-sub-main] => Array
(
[menu_name] => Sub Sub Menu 1
[menu_slug] => menu-sub-sub-main
[parent_menu_slug] => menu-sub-main
)
.
.
)
)
.
.
)
)
[menu-main1] => Array
(
[menu_name] => Menu Name 1
[menu_slug] => menu-main1
[parent_menu_slug] =>
)
..
)
Any help will be appreciated
Upvotes: 2
Views: 362
Reputation: 18557
From link
I have made some function parameters changes as per requirement and to get exact output I changed branch line.
Here is the recursive function to achieve this,
function buildTree(array $elements, $options = [
'parent_id_column_name' => 'parent_menu_slug',
'children_key_name' => 'children',
'id_column_name' => 'menu_slug'], $parentId = '')
{
$branch = array();
foreach ($elements as $element) {
if ($element[$options['parent_id_column_name']] == $parentId) {
// we will call for every node which is having its child using recursion
$children = buildTree($elements, $options, $element[$options['id_column_name']]);
if ($children) { // if it have children array then save it
$element[$options['children_key_name']] = $children;
}
// we will save every node's parent generated recursive data here
$branch[$element['menu_slug']] = $element; // I changed this line
}
}
// recursive generated data returned
return $branch;
}
Here is working demo.
Upvotes: 1