i am trying to create a multidimensional array hierarchy from a simple array which contains pairs of category ids and parent ids. The categories can be a parent and a subcategor
I know, late to the party but it looks interesting...
/*
* This is a 'multiway' tree where:
* a 'parent' can have any number of 'child' nodes
* therefore the 'parent node' must look like:
* [parentId] => array()
*
* where [parentId] is the index of an array;
*/
It will insert one node at a time starting from the root node. It can get very expensive for large trees.
Working example at: Viper-7.com
The routine that does the work:
/**
* Insert: Find the 'parent' node
* if child not found then insert a 'node'
*
* @param array node passed by reference as the new node will be inserted
* @param integer $parentId - root Id must be the lowest value
* @param integer $childId
* @return boolean true if parentId found and processed
*/
function insertNode(&$node, $parentId, $childId) {
if (isset($node[$parentId])) { // this node will be processed
if (!isset($node[$parentId][$childId])) {
$node[$parentId][$childId] = array(); // add child node
return true;
}
return true; // end of processing
}
// check all the children of this node...
foreach($node as &$child) { // need the reference
if (insertNode($child, $parentId, $childId)) {
return true;
}
}
return false; // parentId not in the tree
}
Notes:
The node to be processed is passed by reference.
The processing will end when the 'parent' id is found
The input node list as given is 'child' => 'parent' order which is unusual, it is ok, just remember that in the processing...
Process the input data:
$theTree = array(current($links) => array()); // root
// insert all the child nodes into the tree
foreach($links as $childId => $parentId) {
$inserted = insertNode($theTree, $parentId, $childId);
}
// output the tree
echo '', 'Children are in the same order as the input array.', '
';
print_r($theTree);
echo '
';
The input list needs to be arraged so that the 'tree' will be loaded such that the parent of the child to be added must be in the tree already. i assume that the input list is in the required order already
Test data, sort and display:
# cat_id => parent_id
$links = array(
1 => 0,
2 => 1,
3 => 2,
4 => 0,
5 => 4, // multiple children
11 => 4,
99 => 4,
13 => 11,
6 => 0
);
Output, i added a sub-tree to the original input...
Children are in the same order as the input array.
Array
(
[0] => Array
(
[1] => Array
(
[2] => Array
(
[3] => Array
(
)
)
)
[4] => Array
(
[5] => Array
(
)
[11] => Array
(
[13] => Array
(
)
)
[99] => Array
(
)
)
[6] => Array
(
)
)
)