Skip to content

Instantly share code, notes, and snippets.

@studentIvan
Created September 24, 2013 16:36
Show Gist options
  • Save studentIvan/6687464 to your computer and use it in GitHub Desktop.
Save studentIvan/6687464 to your computer and use it in GitHub Desktop.
EasyTree php tree build algorithm
<?php
/**
* 1. This Algorithm can help you build tree as a nested php array from array like ('id' => x, 'parent_id' => y)
* 2. Algorithm speed = {O(n log n) + О(N)}
*/
class EasyTree
{
public static
$idKeyName = 'id', $parentIdKeyName = 'parent_id', $childrenKeyName = 'children';
protected static function operator($a, $b)
{
return ($a[self::$parentIdKeyName] === $b[self::$parentIdKeyName]) ?
0 : (($a[self::$parentIdKeyName] < $b[self::$parentIdKeyName]) ? -1 : 1);
}
/**
* @return array
*/
public static function build(array $a)
{
$tree = $links = array();
usort($a, "self::operator");
$acmeId = $a[0][self::$parentIdKeyName];
for ($n = count($a), $i = 0; $i < $n; $i++)
{
$id = $a[$i][self::$idKeyName];
$parentId = $a[$i][self::$parentIdKeyName];
if ($parentId === $acmeId)
{
$tree[$id] = $a[$i];
$links[$id] = &$tree[$id];
}
else
{
if (!isset($links[$parentId][self::$childrenKeyName]))
$links[$parentId][self::$childrenKeyName] = array();
$links[$parentId][self::$childrenKeyName][$id] = $a[$i];
$links[$id] = &$links[$parentId][self::$childrenKeyName][$id];
}
}
return $tree;
}
}
/*
print_r(
EasyTree::build(array(
array('id' => 1, 'parent_id' => 0),
array('id' => 3, 'parent_id' => 1),
array('id' => 2, 'parent_id' => 1),
array('id' => 8, 'parent_id' => 0),
array('id' => 4, 'parent_id' => 0),
array('id' => 5, 'parent_id' => 0),
array('id' => 6, 'parent_id' => 0),
array('id' => 7, 'parent_id' => 0),
array('id' => 11, 'parent_id' => 7),
array('id' => 9, 'parent_id' => 0),
array('id' => 10, 'parent_id' => 7),
array('id' => 12, 'parent_id' => 7),
array('id' => 13, 'parent_id' => 7),
array('id' => 14, 'parent_id' => 10),
array('id' => 15, 'parent_id' => 10),
array('id' => 16, 'parent_id' => 15),
array('id' => 17, 'parent_id' => 16),
array('id' => 18, 'parent_id' => 17),
))
);
*/
@Rakasch
Copy link

Rakasch commented Jan 31, 2018

This only works if the parent_ids are guaranteed to be smaller than the child_ids.
If you have a tree that may contain eg. array('id' => 10, 'parent_id' => 99), EasyTree will loose those childs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment