views:

63

answers:

2

I have an array with tree data (by parent id). I want to convert it to multidimensional array. What is the best way to achieve that? Is there any short function for that?

Source array:

$source = array(
    '0' => array(
            'Menu' => array(
                    'id' => 45
                    'name' => 'Home'
                    'parent_id' => 1
            )
    )
    '1' => array(
            'Menu' => array(
                    'id' => 47
                    'name' => 'Get started'
                    'parent_id' => 1
            )
    )
    '2' => array(
            'Menu' => array(
                    'id' => 72
                    'name' => 'Attributes'
                    'parent_id' => 71
            )
    )
    '3' => array(
            'Menu' => array(
                    'id' => 73
                    'name' => 'Headings'
                    'parent_id' => 71
            )
    )
    '4' => array(
            'Menu' => array(
                    'id' => 75
                    'name' => 'Links'
                    'parent_id' => 71
            )
    )
    '5' => array(
            'Menu' => array(
                    'id' => 59
                    'name' => 'Images'
                    'parent_id' => 75
            )
    )
    '6' => array(
            'Menu' => array(
                    'id' => 65
                    'name' => 'Lists'
                    'parent_id' => 75
            )
    )
);

Some parents are missing from the source array. I would like the items with missing parent to be root. Result array:

$result = array(
    '0' => array(
            'Menu' => array(
                    'id' => 45
                    'name' => 'Home'
                    'parent_id' => 1
            )
            'Children' => array()
    )
    '1' => array(
            'Menu' => array(
                    'id' => 47
                    'name' => 'Get started'
                    'parent_id' => 1
            )
            'Children' => array()
    )
    '2' => array(
            'Menu' => array(
                    'id' => 72
                    'name' => 'Attributes'
                    'parent_id' => 71
            )
            'Children' => array()
    )
    '3' => array(
            'Menu' => array(
                    'id' => 73
                    'name' => 'Headings'
                    'parent_id' => 71
            )
            'Children' => array()
    )
    '4' => array(
            'Menu' => array(
                    'id' => 75
                    'name' => 'Links'
                    'parent_id' => 71
            )
            'Children' => array(
                    '0' => array(
                        'Menu' => array(
                            'id' => 59
                            'name' => 'Images'
                            'parent_id' => 75
                        )
                        'Children' => array()
                    )
                    '1' => array(
                        'Menu' => array(
                            'id' => 65
                            'name' => 'Lists'
                            'parent_id' => 75
                        )
                        'Children' => array()
                   )
            )
     )
);

Update: removed square brackets.

A: 

there is no short function to achieve that. You will have to program that.

Itay Moav
+2  A: 

I don't think there is a built-in function in PHP that does this.

I tried the following code, and it seems to work to prepare the nested array the way you describe:

$nodes = array();
$tree = array();
foreach ($source as &$node) {
  $node["Children"] = array();
  $id = $node["Menu"]["id"];
  $parent_id = $node["Menu"]["parent_id"];
  $nodes[$id] =& $node;
  if (array_key_exists($parent_id, $nodes)) {
    $nodes[$parent_id]["Children"][] =& $node;
  } else {
    $tree[] =& $node;
  }
}

var_dump($tree);

I wrote a similar algorithm in a PHP class I wrote for my presentation Hierarchical Models in SQL and PHP, but I was using objects instead of plain arrays.

Bill Karwin
You are fantastic! Thanks for working solution and sush fast answer! The source array is the result of database query.
bancer
Note that this algorithm works only if parents appear up in the db result set before their children appear.
Bill Karwin