Вы хотите минимизировать количество проходов, которые вы делаете, выполняя рекурсивную функцию, которую вы потенциально настраиваете на серьезную проблему производительности позже. Выполняя один проход и используя ссылки, вы можете быстро запустить этот запуск и работать очень хорошо. Использование памяти также будет немного выше, чем исходный набор данных, поскольку все делается по ссылке, а не копией. Если вы обновите одну из записей, все записи будут обновлены.
входной массив
$rows = [
[ 'id' => 1, 'parent' => null ],
[ 'id' => 2, 'parent' => 1 ],
[ 'id' => 3, 'parent' => 1 ],
[ 'id' => 4, 'parent' => 2 ],
[ 'id' => 5, 'parent' => 3 ],
[ 'id' => 6, 'parent' => 4 ],
[ 'id' => 7, 'parent' => 5 ],
[ 'id' => 8, 'parent' => 6 ],
[ 'id' => 9, 'parent' => 7 ],
[ 'id' => 10, 'parent' => 8 ],
];
переменная, где вы будете хранить ваши ссылки
$tree = [];
петля рекорд
foreach($rows as $row) {
проверки здесь, чтобы увидеть, если вы добавили эту строку, в теории это должно всегда вернуться верно, если у вас нет повторяющихся записей
if (
false === array_key_exists($row['id'], $tree) ||
false === array_key_exists('data', $tree[$row['id']])
) {
$tree[$row['id']]['data'] = $row;
}
проверяя, если вы иметь родителя, а затем, если родитель был добавлен еще и/или если его дети были инициализированы
if (
$row['parent'] &&
(
false === array_key_exists($row['parent'], $tree) ||
false === array_key_exists('children', $tree[$row['parent']])
)
) {
$tree[$row['parent']]['children'] = [];
}
добавить ссылку ребенка на родителей, проявлять особую осторожность, чтобы отметить &, который говорит, что это по ссылке
if ($row['parent']) {
$tree[$row['parent']]['children'][] = &$tree[$row['id']];
}
}
$ дерево становится следующим
[
1 =>
[
'data' =>
[
'id' => 1,
'parent' => NULL,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 2,
'parent' => 1,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 4,
'parent' => 2,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 6,
'parent' => 4,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 8,
'parent' => 6,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 10,
'parent' => 8,
],
],
],
],
],
],
],
],
],
],
1 =>
[
'data' =>
[
'id' => 3,
'parent' => 1,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 5,
'parent' => 3,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 7,
'parent' => 5,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 9,
'parent' => 7,
],
],
],
],
],
],
],
'name' => 'test',
],
],
],
2 =>
[
'data' =>
[
'id' => 2,
'parent' => 1,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 4,
'parent' => 2,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 6,
'parent' => 4,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 8,
'parent' => 6,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 10,
'parent' => 8,
],
],
],
],
],
],
],
],
],
],
3 =>
[
'data' =>
[
'id' => 3,
'parent' => 1,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 5,
'parent' => 3,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 7,
'parent' => 5,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 9,
'parent' => 7,
],
],
],
],
],
],
],
'name' => 'test',
],
4 =>
[
'data' =>
[
'id' => 4,
'parent' => 2,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 6,
'parent' => 4,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 8,
'parent' => 6,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 10,
'parent' => 8,
],
],
],
],
],
],
],
],
5 =>
[
'data' =>
[
'id' => 5,
'parent' => 3,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 7,
'parent' => 5,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 9,
'parent' => 7,
],
],
],
],
],
],
6 =>
[
'data' =>
[
'id' => 6,
'parent' => 4,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 8,
'parent' => 6,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 10,
'parent' => 8,
],
],
],
],
],
],
7 =>
[
'data' =>
[
'id' => 7,
'parent' => 5,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 9,
'parent' => 7,
],
],
],
],
8 =>
[
'data' =>
[
'id' => 8,
'parent' => 6,
],
'children' =>
[
0 =>
[
'data' =>
[
'id' => 10,
'parent' => 8,
],
],
],
],
9 =>
[
'data' =>
[
'id' => 9,
'parent' => 7,
],
],
10 =>
[
'data' =>
[
'id' => 10,
'parent' => 8,
],
],
]
спасибо за подробный ответ. Что произойдет с огромным объемом данных, которые вы принимаете в качестве входного массива «$ rows». Мне нужно получить все данные верхнего уровня для конкретного ребенка, как указано в приведенном выше снимке экрана. Я думаю, чтобы получить родительский идентификатор для каждого конкретного идентификатора и сохранить его, пока родитель не будет NULL. Как вы думаете, вы можете предоставить мне работоспособный образец для моей конкретной потребности? Буду признателен за вашу помощь и поддержку –