1

Okay, basically, I have formed a mySQL query which returns a data set all sorted perfectly of my data structure. If I was to declare it, it would look something like this:

$arr = array(
        array( 'name' => 'Root', 'depth' => 0 ),
        array( 'name' => 'Food', 'depth' => 0 ),
        array( 'name' => 'Fruit', 'depth' => 1 ),
        array( 'name' => 'Bannnanna', 'depth' => 2 ),
        array( 'name' => 'Apple', 'depth' => 2 ),
        array( 'name' => 'Bannnanna', 'depth' => 2 ),
        array( 'name' => 'Meat', 'depth' => 1 ),
        array( 'name' => 'Furniture', 'depth' => 0 )
        );

What I want, is to feed this $arr into a method so that I can then get a multi-dimensional array back.

For instance, Fruit would be a child of Food. And Bananana would be a child of Fruit. I need the keys of each 'child' to be 'pages'.

The array that I showed above can also return other information such as 'lft' and 'rgt'. I do not have 'parentId' set but I can change my model if its required, but I would prefer to stick with Nested Set Model.

jzd
  • 23,473
  • 9
  • 54
  • 76
Layke
  • 51,422
  • 11
  • 85
  • 111

2 Answers2

5

something like this maybe

            $arr = array(
                    array( 'name' => 'Root', 'depth' => 0 ),
                    array( 'name' => 'Food', 'depth' => 0 ),
                    array( 'name' => 'Fruit', 'depth' => 1 ),
                    array( 'name' => 'Bannnanna', 'depth' => 2 ),
                    array( 'name' => 'Apple', 'depth' => 2 ),
                    array( 'name' => 'Bannnanna', 'depth' => 2 ),
                    array( 'name' => 'Meat', 'depth' => 1 ),
                    array( 'name' => 'Furniture', 'depth' => 0 )
                    );

            $p = array(array());
            foreach($arr as $n => $a) {
                $d = $a['depth'] + 1;
                $p[$d - 1]['children'][] = &$arr[$n];
                $p[$d] = &$arr[$n];
            }

            print_r($p[0]);
user187291
  • 53,363
  • 19
  • 95
  • 127
4

The following code assumes that the order and depth of your values are correct. Note that it removes the duplicates by using keys.

 header('Content-Type: text/plain');

 $arr = array(
     array( 'name' => 'Root', 'depth' => 0 ),
     array( 'name' => 'Food', 'depth' => 0 ),
     array( 'name' => 'Fruit', 'depth' => 1 ),
     array( 'name' => 'Bannnanna', 'depth' => 2 ),
     array( 'name' => 'Apple', 'depth' => 2 ),
     array( 'name' => 'Bannnanna', 'depth' => 2 ),
     array( 'name' => 'Meat', 'depth' => 1 ),
     array( 'name' => 'Furniture', 'depth' => 0 )
 );

 function process( &$arr, &$prev_sub = null, $cur_depth = 0 ) {
  $cur_sub = array();
  while( $line = current( $arr ) ) {
   if( $line['depth'] < $cur_depth ) {
    return $cur_sub;
   } elseif( $line['depth'] > $cur_depth ) {
    $prev_sub = process( $arr, $cur_sub, $cur_depth + 1 );
   } else {
    $cur_sub[$line['name']] = $line['name'];
    $prev_sub =& $cur_sub[$line['name']];
    next( $arr );
   }
  }
  return $cur_sub;
 }

 $values = process( $arr );
 print_r( $values );

Output:

 Array
 (
     [Root] => Root
     [Food] => Array
         (
             [Fruit] => Array
                 (
                     [Bannnanna] => Bannnanna
                     [Apple] => Apple
                 )
             [Meat] => Meat
         )
     [Furniture] => Furniture
 )
instanceof me
  • 38,520
  • 3
  • 31
  • 40
  • This is exactly what I've been looking for, works great! Are you able to post how to add additional fields though? – dzm Sep 27 '11 at 01:41