On Thu, Jan 12, 2012 at 12:14 PM, David Skinner
<[email protected]> wrote:
> 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.
>
> Each element of the starting array is read from a separate XML file which
> is created by a 3rd party app. The file itself will have '0' as the value
> for parent_id if it doesn't have a parent. The keys are actually strings.
>
> My starting array:

For what it's worth, here's what I thought might work as we were
discussing this in IRC:

1. Start by making a list of all the children for each parent:

$lists = array();

foreach ($startingarray as $k => $v) {
  $lists[$v['parent_id']][$k] = $v;
}

That should give you something like this:

Array
   (
    [0] => Array
       (
           [_319_] => Array
           (
               [id] => 0
               [parent_id] => 0
           )

           [_320_] => Array
           (
               [id] => _320_
               [parent_id] => 0
           )

           [_323_] => Array
           (
               [id] => _323_
               [parent_id] => 0
           )
      )

    [_320_] => Array
      (
           [_321_] => Array
           (
               [id] => _321_
               [parent_id] => _320_
           )

           [_325_] => Array
           (
               [id] => _325_
               [parent_id] => _320_
           )
      )

    [_321_] => Array
      (
           [_322_] => Array
           (
               [id] => _322_
               [parent_id] => _321_
           )

    [_323_] => Array
      (
           [_324_] => Array
           (
               [id] => _324_
               [parent_id] => _323_
           )
      )
   )

2. Next, assemble the tree:

function buildTree( $tree, &$lists) {
  foreach ($tree as $k => $v) {
    // If we have any children for this node, link them in:
    if (isset($lists[$k])) {
      $tree[$k]['children'] = $lists[$k];
      unset($lists[$k]);
      // Then go in and find any of that node's children and link them in:
      $tree[$k] = buildTree($tree[$k], $lists);
    }
  }
  return $tree;
}

$tree = buildTree($lists[0], $lists);

I think that should make the structure you're looking for, with one
pass through the original list, and one depth-first traversal of the
tree.

Thanks,
Mac


-- 
Mac Newbold
[email protected]
801-694-6334

_______________________________________________

UPHPU mailing list
[email protected]
http://uphpu.org/mailman/listinfo/uphpu
IRC: #uphpu on irc.freenode.net

Reply via email to