I have a multidimensional array with parent-child relationships and I want to flatten its data into a 2d array of the scalar data from each level using recursion.
[
'children' => [
[
'id' => 123,
'title' => 'test',
'children' => [
[
'id' => 345,
'title' => 'test 1',
'children' => [],
],
[
'id' => 567,
'title' => 'test 2',
'children' => [
[
'id' => 789,
'title' => 'test 3',
'children' => [],
],
[
'id' => 333,
'title' => 'tset 4',
'children' => [
[
'id' => 222,
'title' => 'test 5',
'children' => [],
],
[
'id' => 111,
'title' => 'test 55',
'children' => [],
],
[
'id' => 444,
'title' => 'test 556',
'children' => [],
],
[
'id' => 666,
'title' => 'test44',
'children' => [],
],
],
],
[
'id' => '5556',
'identifier' => 'test 2',
'children' => [
[
'id' => 888,
'title' => 'test 2',
'children' => [],
],
[
'id' => 255,
'title' => 'tset',
'children' => [],
],
[
'id' => 454,
'title' => 'warm-up-5837',
'children' => [],
],
],
],
],
],
],
],
],
];
My current code:
function flattenTree(array $elements, $i, $branch)
{
foreach($elements as $element) {
$branch[$i++] = [
'id' => $element['id'],
'title' => $element['title']
];
if (!empty($element['children'])) {
flattenTree($element['children'], $i, $branch);
}
}
return $branch;
}
Desired output:
Array
(
[0] => [
[id] => 123
[title] => 'test'
]
[1] => [
[id] => 345
[title] => 'test 1'
]
[2] => [
[id] => 567
[title] => 'test 2'
]
[3] => [
[id] => 789
[title] => 'test 3'
]
[4] => [
[id] => 333
[title] => 'tset 4'
]
[5] => [
[id] => 222
[title] => 'test 5'
]
[6] => [
[id] => 111
[title] => 'test 55'
]
[7] => [
[id] => 444
[title] => 'test 556'
]
[8] => [
[id] => 666
[title] => 'test44'
]
[9] => [
[id] => '5556'
[identifier] => 'test 2'
]
[10] => [
[id] => 888
[title] => 'test 2'
]
[11] => [
[id] => 255
[title] => 'tset'
]
)
2
Answers
Ok, a couple of observations.
You are using
$i
. This pointer needs to be passed by reference in every subsequent method call, else the previous$i
location will be overridden when the recursive call comes back.You are adding results to
$branch
. Now, you would again wish to pass this as a reference to affect the same output variable.return $branch;
This is entirely not needed if you passing the output variable pass by reference.Snippet:
Your coding attempt looks more complicated than necessary.
children
element of whatever array is passed into the recursive function.id
andtitle
/identifier
data.children
element, then make the recursive call and push its returned payload as individual elements into the parent’s cache.There is no need to maintain a counter.
Code: (Demo)
If you want to keep that
identifier
key in the output, then you can merely filter the$child
data withis_scalar()
before caching. (Demo)