Skip to content

Instantly share code, notes, and snippets.

@MubinSayed
Forked from ubermaniac/covertToHierarchy.php
Created April 12, 2019 12:32
Show Gist options
  • Select an option

  • Save MubinSayed/6ae47ef62038d0ae164adb6995fc3350 to your computer and use it in GitHub Desktop.

Select an option

Save MubinSayed/6ae47ef62038d0ae164adb6995fc3350 to your computer and use it in GitHub Desktop.
Convert a DB result of parent/child items into a hierarchical array
<?php
// -- Only one caveat : The results must be ordered so that an item's parent will be processed first.
// -- Simulate a DB result
$results = array();
$results[] = array('id' => 'a', 'parent' => '', 'name' => 'Johnny');
$results[] = array('id' => 'b', 'parent' => 'a', 'name' => 'Bobby');
$results[] = array('id' => 'c', 'parent' => 'b', 'name' => 'Marky');
$results[] = array('id' => 'd', 'parent' => 'a', 'name' => 'Ricky');
$results[] = array('id' => 'e', 'parent' => '', 'name' => 'Timmy');
$results[] = array('id' => 'g', 'parent' => 'f', 'name' => 'Mary'); // -- child showing before parent, to demonstrate shuffling after initial pass
$results[] = array('id' => 'f', 'parent' => 'e', 'name' => 'Tommy');
$results[] = array('id' => 'h', 'parent' => 'b', 'name' => 'Donny');
function convertToHierarchy($results) {
$hierarchy = array(); // -- Stores the final data
$itemReferences = array(); // -- temporary array, storing references to all items in a single-dimention
foreach ( $results as $item ) {
$parent = $item['parent'];
if (isset($itemReferences[$parent])) { // parent exists
$itemReferences[$parent]['children'][$item['id']] = $item; // assign item to parent
$itemReferences[$item['id']] =& $itemReferences[$parent]['children'][$item['id']]; // reference parent's item in single-dimentional array
} elseif (!$parent || !isset($hierarchy[$parent])) { // -- parent value is empty. It is a root item
$hierarchy[$item['id']] = $item;
$itemReferences[$item['id']] =& $hierarchy[$item['id']];
}
}
// -- Run through the root one more time. If any child got added before it's parent, fix it.
foreach ( $hierarchy as $id => &$h ) {
if ( isset($itemReferences[$h['parent']] ) ) { // -- parent DOES exist
$itemReferences[$h['parent']]['children'][$h['id']] = $h; // -- assign it to the parent's list of children
unset($hierarchy[$id]); // -- remove it from the root of the hierarchy
}
}
unset($itemReferences, $item, $results, $parent);
return $hierarchy;
}
print_r(convertToHierarchy($results));
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment