Skip to content

Instantly share code, notes, and snippets.

@Sumurai8
Last active February 5, 2018 22:12
Show Gist options
  • Save Sumurai8/f770a2b76fd5236c4cbe644091f31d20 to your computer and use it in GitHub Desktop.
Save Sumurai8/f770a2b76fd5236c4cbe644091f31d20 to your computer and use it in GitHub Desktop.
Add "descendants" and "children" property to collection of nodes in nested set format
<?php
/**
* Adds the children and descendants attribute to an ordered set of nodes
*
* @param array $nodes pre-order walk of nodes in nested set format
*/
function with_descendants_and_children(array $nodes) {
// First we initialise our stack
$ancestor_stack = [];
// Then we run through ordered nodes
for ($i = 0; $i < count($nodes); $i++) {
// Each node has at least an empty descendants/children attribute
$nodes[$i]['descendants'] = [];
$nodes[$i]['children'] = [];
// Purge the nodes from our stack that are
// our sibling sor our ancestors siblings
while (
!empty($ancestor_stack) &&
$nodes[$i]['left'] > $nodes[end($ancestor_stack)]['right']
) {
array_pop($ancestor_stack);
}
// Each ancestor has this node as a descendant
foreach ($ancestor_stack as $ancestor_id) {
$nodes[$ancestor_id]['descendants'][] = $nodes[$i]['title'];
}
// The last ancestor is also our parent
$nodes[end($ancestor_stack)]['children'][] = $nodes[$i]['title'];
// In case this node has descendants, we need to add this
// node to the ancestor stack for future nodes we process
$ancestor_stack[] = $i;
}
return $nodes;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment