Сглаживание многопоточного массива JSON в переполнении стека

Доброе утро, учитывая структуру данных ниже (в JSON для удобства чтения)

[
{
"parent": "root",
"active": "1",
"label": "Index",
"route": "/",
"children": [
{
"parent": "/",
"active": "1",
"label": "Products",
"route": "/products",
"children": [
{
"parent": "/products",
"active": "0",
"label": "Test",
"route": "/test"}
]
}
]
},
{
"parent": "root",
"active": "1",
"label": "404",
"route": "/404"},
{
"parent": "root",
"active": "1",
"label": "Login",
"route": "/login"}
]

У меня большие проблемы с возвратом из функции следующей структуры:

[
{
"parent": "root",
"active": "1",
"label": "Index",
"route": "/"},
{
"parent": "/products",
"active": "0",
"label": "Test",
"route": "/test"},
{
"parent": "/",
"active": "1",
"label": "Products",
"route": "/products"},
{
"parent": "root",
"active": "1",
"label": "404",
"route": "/404"},
{
"parent": "root",
"active": "1",
"label": "Login",
"route": "/login"}
]

По сути, я хочу пройти через все дочерние элементы и заполнить новый массив каждым родителем и дочерним элементом во вложенных массивах, я пробовал array_merge, RecursiveIteratorIterator, itterator_to_array, array_map, но он всегда отклеивается от рекурсии. Мне удалось сделать это, когда дети были всего на один уровень глубиной, а два или более просто сломались.

Пожалуйста помоги!

3

Решение

Не очень сложно

function flatten(array $array) {
$branch = [];

foreach ($array as $item) {
$children = [];
if (isset($item['children']) && is_array($item['children'])) {
$children = flatten($item['children']);
unset($item['children']);
}
$branch = array_merge($branch, [$item], $children);
}

return $branch;
}
1

Другие решения

Очень просто

function flatten($items, &$r) {
foreach($items as $item) {
$c = isset($item->children) ? $item->children : null;
unset($item->children);
$r []= $item;
if($c)
flatten($c, $r);
}
}

flatten(json_decode($json), $r);
print_r($r);

Это накапливает результаты в одном буфере, переданном по ссылке. Это гораздо эффективнее, чем создание нового массива на каждой итерации, что в основном является вариацией Алгоритм художника Шлемеля.

Если вы предпочитаете функциональный подход, вы можете использовать генераторы:

function flatten($items) {
foreach($items as $item) {
$c = isset($item->children) ? $item->children : [];
unset($item->children);
yield $item;
foreach(flatten($c) as $child)
yield $child;
}
}

foreach(flatten(json_decode($json)) as $item)
print_r($item);
3

По вопросам рекламы [email protected]