I have a list of items in a PHP array, and I’m trying to write a function to get the values for the relative 3 lowest levels from each array block. I could format the array hierarchically based on the parent_id field, but now I’d like to filter it down to the relative 3 lowest levels only.
Here is the array that I’m working with (the values are just examples):
array (
0 =>
array (
'id' => 1,
'parent_id' => NULL,
'name' => 'Home',
'children' =>
array (
0 =>
array (
'id' => 3,
'parent_id' => 1,
'name' => 'Contact',
'children' =>
array (
0 =>
array (
'id' => 6,
'parent_id' => 3,
'name' => 'Phone',
),
1 =>
array (
'id' => 7,
'parent_id' => 3,
'name' => 'Email',
),
),
),
),
),
1 =>
array (
'id' => 2,
'parent_id' => NULL,
'name' => 'About',
'children' =>
array (
0 =>
array (
'id' => 4,
'parent_id' => 2,
'name' => 'History',
),
1 =>
array (
'id' => 5,
'parent_id' => 2,
'name' => 'Team',
'children' =>
array (
0 =>
array (
'id' => 8,
'parent_id' => 5,
'name' => 'John',
'children' =>
array (
0 =>
array (
'id' => 12,
'parent_id' => 8,
'name' => 'John 2',
),
),
),
1 =>
array (
'id' => 10,
'parent_id' => 5,
'name' => 'Alex',
),
),
),
),
),
2 =>
array (
'id' => 9,
'parent_id' => 22,
'name' => 'Mary',
),
)
The PHP function I’m trying to write should result in the following output:
-
About
-
History
-
Team
- John
-
-
Home
-
Contact
-
Phone
-
Email
-
-
-
Mary
With real data, there might be more or fewer levels, so the function should be able to find the lowest levels, no matter if there are only 4 (as in this example), or 12.
I was able to write a function that returns the top 3 levels from the array, but I’m looking for a good way to return the bottom 3 levels of each array block.
Thanks for the help in advance!
Additional context
The original array from PHP:
$flat_array = array(
array('id' => 1, 'parent_id' => null, 'name' => 'Home'),
array('id' => 2, 'parent_id' => 1, 'name' => 'About'),
array('id' => 3, 'parent_id' => 1, 'name' => 'Contact'),
array('id' => 4, 'parent_id' => 2, 'name' => 'History'),
array('id' => 5, 'parent_id' => 2, 'name' => 'Team'),
array('id' => 6, 'parent_id' => 3, 'name' => 'Phone'),
array('id' => 7, 'parent_id' => 3, 'name' => 'Email'),
array('id' => 8, 'parent_id' => 5, 'name' => 'John'),
array('id' => 9, 'parent_id' => 11, 'name' => 'Mary'),
);
The function I’m transforming this with into a hierarchical array:
function hierarchyOrder($flat_array) {
$resultIds = get_ids(($flat_array));
$map = array();
foreach ($flat_array as $arr) {
$map[$arr['id']] = $arr;
}
$hierarchy = array();
foreach ($flat_array as $arr) {
if (($arr['parent_id'] !== null) AND (in_array($arr["parent_id"], $resultIds))) {
$map[$arr['parent_id']]['children'][] = &$map[$arr['id']];
}
else {
$hierarchy[] = &$map[$arr['id']];
}
}
return $hierarchy;
}
function get_ids($flat_array) {
return array_map(function($item) {
return $item['id'];
}, $flat_array);
}
Previously, I tried to build up the function by modifying a similar function that returns the top 3 levels of an array. My solution was not dynamic enough, and I was not able to figure out a logic that reliably can return the bottom 3 levels. My starting point was:
function returnCorrectLevels($input) {
$result = [];
foreach ($input as $item) {
$level1 = [
'id' => $item['id'],
'parent_id' => $item['parent_id'],
'name' => $item['name'],
];
if (isset($item['children'])) {
$level2 = [];
foreach ($item['children'] as $child1) {
$level2[] = [
'id' => $child1['id'],
'parent_id' => $child1['parent_id'],
'name' => $child1['name'],
];
if (isset($child1['children'])) {
$level3 = [];
foreach ($child1['children'] as $child2) {
$level3[] = [
'id' => $child2['id'],
'parent_id' => $child2['parent_id'],
'name' => $child2['name'],
];
}
$level2[count($level2)-1]['children'] = $level3;
}
}
$level1['children'] = $level2;
}
$result[] = $level1;
}
return $result;
}
2
Answers
Initially, as per the desired output mentioned in the question, the
parent_id
of About menu item has to benull
.Final output will be as follows:
Screenshot of final output as desired
Edited after reading the comments provided by the author
The above code is accommodating
n
number of levels, picking the bottom 3 levels is bit challenging with current example given.You can try to positively arranged if the array is sored decending from bottom to top. You can try as per my comment below.
ok i fix it
and you have output page code