Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build a tree from a flat array in PHP

I've looked around the internet and haven't quite found what I'm looking for. I have a flat array with each element containing an 'id' and a 'parent_id'. Each element will only have ONE parent, but may have multiple children. If the parent_id = 0, it is considered a root level item. I'm trying to get my flat array into a tree. The other samples I have found only only copy the element to the parent, but the original still exists.

EDIT

Each element of the starting array is read from a separate XML file. The file itself will have '0' as the value for parent_id if it doesn't have a parent. The keys are actually strings.

I'm sorry for the confusion earlier. Hopefully this is more clear:

/EDIT

My starting array:

 Array (     [_319_] => Array         (             [id] => 0             [parent_id] => 0         )      [_320_] => Array         (             [id] => _320_             [parent_id] => 0         )      [_321_] => Array         (             [id] => _321_             [parent_id] => _320_         )      [_322_] => Array         (             [id] => _322_             [parent_id] => _321_         )      [_323_] => Array         (             [id] => _323_             [parent_id] => 0         )      [_324_] => Array         (             [id] => _324_             [parent_id] => _323_         )      [_325_] => Array         (             [id] => _325_             [parent_id] => _320_         ) )

The resulting array after the tree is made:

 Array (     [_319_] => Array         (             [id] => _319_             [parent_id] => 0         )      [_320_] => Array         (             [id] => _320_             [parent_id] => 0             [children] => Array                 (                     [_321_] => Array                         (                             [id] => _321_                             [parent_id] => _320_                             [children] => Array                                 (                                     [_322_] => Array                                         (                                             [id] => _322_                                             [parent_id] => _321_                                         )                                 )                         )                     [_325_] => Array                         (                             [id] => _325_                             [parent_id] => _320_                         )                 )     [_323_] => Array         (             [id] => _323_             [parent_id] => 0             [children] => Array                 (                     [_324_] => Array                         (                             [id] => _324_                             [parent_id] => _323_                         )                 )         ) 

Any help / guidance is greatly appreciated!

Some code I have so far:

          function buildTree(array &$elements, $parentId = 0) {         $branch = array();          foreach ($elements as $element) {             if ($element['parent_id'] == $parentId) {                 $children = $this->buildTree($elements, $element['id']);                 if ($children) {                     $element['children'] = $children;                 }                 $branch[] = $element;             }         }          return $branch;     }  
like image 243
DSkinner Avatar asked Jan 12 '12 18:01

DSkinner


2 Answers

You forgot the unset() in there bro.

function buildTree(array &$elements, $parentId = 0) {     $branch = array();      foreach ($elements as $element) {         if ($element['parent_id'] == $parentId) {             $children = buildTree($elements, $element['id']);             if ($children) {                 $element['children'] = $children;             }             $branch[$element['id']] = $element;             unset($elements[$element['id']]);         }     }     return $branch; } 
like image 66
n0nag0n Avatar answered Sep 21 '22 11:09

n0nag0n


The solution by ImmortalFirefly is working, however, as mrded points out, it doesn't save first parents without children. I've edited the function to fix this issue:

function buildTree(array &$elements, $parentId = 0) {      $branch = array();      foreach ($elements as &$element) {          if ($element['parent_id'] == $parentId) {             $children = buildTree($elements, $element['id']);             if ($children) {                 $element['children'] = $children;             }             $branch[$element['id']] = $element;             unset($element);         }     }     return $branch; } 
like image 20
SteveEdson Avatar answered Sep 20 '22 11:09

SteveEdson