2010-09-28 6 views
1

У меня есть массив в php с объектами, содержащими id и parent_id. Все объекты без родительского элемента должны быть корневыми объектами в новом массиве.PHP массив для многомерного массива

Все объекты, которые сделать имеют 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 
), 
); 

Любая идея, как я мог это сделать?

+0

Зачем вам нужен массив в другом формате? Похоже, что у вас есть вся информация в первом массиве –

+0

Я думаю, что легче использовать его в качестве справочной таблицы позже, потому что я должен иметь возможность динамически добавлять/редактировать/удалять объекты и заменять их от одного родителя к другому – Yens

+0

Hm , Я согласен с Филлом Паффордом. Единственное полезное преимущество, которое я вижу, заключается в том, что получение всех детей для родителя может выполняться в постоянное время, а не в линейном. Кроме того, переход от одного родителя к другому на самом деле становится сложнее. – erisco

ответ

5

попробовать что-то вроде этого:

// 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); 

Этот код рекурсивно ищет в исходной $nodeList данной parent_id. Если найден соответствующий узел, он ищет дочерние элементы этого узла и т. Д. Если не найдено ни одного дочернего объекта для заданного parent_id, пустой массив будет перенастроен.

Вы можете уменьшить использование памяти этого подхода, используя ссылки для $nodeList.

+0

Спасибо! это именно то, что мне нужно! Не знал, что это было так просто :) – Yens

+0

@yens resmann: Рекурсия действительно мощная, как вы можете видеть;) Используйте ее с осторожностью. – jwueller

+0

+1 если вы можете сделать это с большей функциональностью. – erisco

Смежные вопросы