У меня есть массив в php с объектами, содержащими id и parent_id . Все объекты без родительского элемента должны быть корневыми объектами в новом массиве.
Все объекты, у которых есть родительский элемент, должны быть помещены в правильный дочерний массив объекта:
Итак, это мой оригинальный массив:
array 0 => object(Node)[528] protected 'id' => int 1 protected 'parent_id' => null 1 => object(Node)[529] protected 'id' => int 2 protected 'parent_id' => null 2 => object(Node)[530] protected 'id' => int 3 protected 'parent_id' => 1 3 => object(Node)[531] protected 'id' => int 4 protected 'parent_id' => 1 4 => object(Node)[532] protected 'id' => int 5 protected 'parent_id' => 4 5 => object(Node)[533] protected 'id' => int 6 protected 'parent_id' => 4
это то, как должен выглядеть новый массив:
$nodes = array( array( 'id' => 1, 'parent_id' => null, 'children' => array( array( 'id' => 3, 'parent_id' => 1, 'children' => null ), array( 'id' => 4, 'parent_id' => 1, 'children' => array( array( 'id' => 5, 'parent_id' => 4 ), array( 'id' => 6, 'parent_id' => 5 ), ) ), ), ), array( 'id' => 2, 'parent_id' => null, 'children' => null ), );
Любая идея, как я могу это сделать?
Попробуйте что-то вроде этого:
// collects all nodes that belong to a certain parent id function findChildren($nodeList, $parentId = null) { $nodes = array(); foreach ($nodeList as $node) { if ($node['parent_id'] == $parentId) { $node['children'] = findChildren($nodeList, $node['id']); $nodes[] = $node; } } return $nodes; }
Используйте его так:
$nestedNodes = findChildren($nodeList);
Этот код рекурсивно ищет данный parent_id
в исходном $nodeList
. Если найден соответствующий узел, он ищет дочерние элементы этого узла и т. Д. Если не найдено ни одного parent_id
для данного parent_id
, пустой массив будет перенастроен.
Вы могли бы уменьшить использование памяти этого подхода, используя ссылки для $nodeList
.