Skip to content

Instantly share code, notes, and snippets.

@sorbing
Last active November 24, 2018 16:20
Show Gist options
  • Save sorbing/a6828d0e31c4e882e7edce583b5a8839 to your computer and use it in GitHub Desktop.
Save sorbing/a6828d0e31c4e882e7edce583b5a8839 to your computer and use it in GitHub Desktop.
Build Tree objects and print it from flatten array with parentId keys.
<?php
class BinaryTree
{
private $items = [];
private $tree;
public function __construct($items)
{
foreach ($items as $item) {
$item = (object)$item;
$this->items[$item->id] = $item;
}
usort($this->items, function($a, $b) {
return $a->parentId > $b->parentId;
});
}
public static function fromArray(array $items)
{
return new self($items);
}
public function build()
{
$tree = $this->buildTree($this->items);
$this->tree = reset($tree);
return $this;
}
private function buildTree(array &$nodes, $parentId = 0) {
$tree = [];
foreach ($nodes as $node) {
if ($node->parentId == $parentId) {
$children = $this->buildTree($nodes, $node->id);
if ($children) {
$leaves = array_values($children);
isset($leaves[0]) && $node->left = $leaves[0];
isset($leaves[1]) && $node->right = $leaves[1];
}
$tree[$node->id] = $node;
unset($nodes[$node->id]);
}
}
return $tree;
}
public function dump()
{
print_r($this->tree);
}
public function render()
{
return $this->renderTree($this->tree);
}
public function renderTree($node, $depth = 0)
{
if ($depth >= 5) {
return '';
}
$html = "<div>";
$html .= "<h2><span>{$node->id}</span></h2>";
if (!empty($node->left)) {
$html .= "<div class='left'>" . $this->renderTree($node->left, $depth+1) . "</div>";
}
if (!empty($node->right)) {
$html .= "<div class='right'>" . $this->renderTree($node->right, $depth+1) . "</div>";
}
$html .= "</div>";
return $html;
}
}
$items = [
['id' => 1, 'parentId' => 0],
['id' => 2, 'parentId' => 1],
['id' => 5, 'parentId' => 1],
['id' => 4, 'parentId' => 2],
['id' => 3, 'parentId' => 2],
['id' => 6, 'parentId' => 3],
['id' => 7, 'parentId' => 6],
['id' => 8, 'parentId' => 7],
['id' => 9, 'parentId' => 8],
];
$tree = BinaryTree::fromArray($items);
//$tree->build()->dump();
$html = $tree->build()->render();
?>
<style>
body {text-align: center; }
h2 { margin: 5px 0; }
h2 span { background-color: #5b8039; padding: 5px; }
.left, .right { width: 50%; vertical-align:top; }
.left { float: left; }
.right { float: right; }
</style>
<?= $html ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment