I have an array like this:
array( array(id => 7, parent_id => 0, name => Current Assets) array(id => 8, parent_id => 0, name => Fixed Assets) array(id => 18, parent_id => 7, name => Assets) array(id => 38, parent_id => 18, name => Receivable) array(id => 38, parent_id => 18, name => Inventory) array(id => 39, parent_id => 0, name => Landed Cost Of Inventory) array(id => 40, parent_id => 38, name => Jazz Cash) array(id => 41, parent_id => 39, name => Advance to Vendors) )
Now I need some efficient way to convert this into tree structure like this.
array( array(id => 7, parent_id => 0, name => Current Assets, level=>0) array(id => 8, parent_id => 0, name => Fixed Asset, level => ) array(id => 18, parent_id => 7, name => Assets, level => 1) array(id => 38, parent_id => 18, name => Inventory, level => 2) array(id => 39, parent_id => 0, name => Landed Cost Of Inventory, level => 0) array(id => 40, parent_id => 38, name => Jazz Cash, level => 3) array(id => 41, parent_id => 39, name => Advance to Vendors, level => 1) )
I no need to add them left or right, I just need the simple levels that I will pass to jQgrid.
Advertisement
Answer
Collect all ids in the order of parent -> child
in an array where parent_id
is the key and it has an array of all child IDs. Second step is to just traverse the tree and assign the ranks.
<?php function assignLevels(&$data){ $kids = []; foreach($data as $d){ $kids[ $d['parent_id'] ] = $kids[ $d['parent_id'] ] ?? []; $kids[ $d['parent_id'] ][] = $d['id']; } $data = array_column($data, null, 'id'); traverseTree($kids, 0, $data); $data = array_values($data); } function traverseTree($kids, $id, &$data, $level = 0){ foreach($kids[ $id ] as $sub_id){ $data[ $sub_id ]['level'] = $level; if(isset($kids[ $sub_id ] )) traverseTree($kids, $sub_id, $data, $level + 1); } } assignLevels($data); print_r($data);