Работа с деревом в виде вложенного множества
This commit is contained in:
commit
d32455d043
5 changed files with 866 additions and 0 deletions
79
src/Sort.php
Normal file
79
src/Sort.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Сортировка дерева в представлении Nested Set
|
||||
* Для дерева которое хранится в базе данных используя представление Nested Set нет возможности отсортировать элементы дерева по
|
||||
* произвольному полю. Поэтому после извлечения дерева из базы данных оно преобразуется в обычное представление сортируется и обратно
|
||||
*
|
||||
* Пример:
|
||||
* $sort = new Tree_Sort();
|
||||
* $data = $sort->sortBy($data, 'name');
|
||||
*/
|
||||
class Tree_Sort {
|
||||
private $data = array();
|
||||
private $result = array();
|
||||
private $sortBy = '';
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
// Преобразуем Nested Set в дерево и сортируем
|
||||
private function listTree(array $tree, $offset, $level) {
|
||||
$result = array();
|
||||
for ($i = $offset; $i < sizeof($tree); $i++) {
|
||||
$leaf = $tree[$i];
|
||||
$clevel = $leaf['cat_level'];
|
||||
if ($clevel == $level) {
|
||||
$result [] = array($i);
|
||||
} else if ($clevel > $level) {
|
||||
list($subtree, $i) = $this->listTree($tree, $i, $clevel);
|
||||
$i--;
|
||||
$result[sizeof($result) - 1][1] = $subtree;
|
||||
} else {
|
||||
$this->sortList($result, $tree);
|
||||
return array($result, $i);
|
||||
}
|
||||
}
|
||||
$this->sortList($result, $tree);
|
||||
return array($result, $i);
|
||||
}
|
||||
|
||||
// Сравнение двух элементов
|
||||
private function compare($a, $b) {
|
||||
$a1 = $this->data[$a[0]][$this->sortBy];
|
||||
$b1 = $this->data[$b[0]][$this->sortBy];
|
||||
return strcmp($a1, $b1);
|
||||
}
|
||||
|
||||
// Сортировка списка
|
||||
private function sortList(array &$list, $data) {
|
||||
usort($list, array($this, 'compare'));
|
||||
}
|
||||
|
||||
// Создает дерево в виде списка
|
||||
private function reorder(array $tree) {
|
||||
foreach($tree as $node) {
|
||||
$this->result[] = $this->data[$node[0]];
|
||||
if (isset($node[1])) {
|
||||
$this->reorder($node[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function sortBy0(array $data, $sortBy)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->sortBy = $sortBy;
|
||||
$order = $this->listTree($data, 0, 0);
|
||||
return $order[0];
|
||||
}
|
||||
|
||||
// Сортировка по заданному полю
|
||||
public function sortBy(array $data, $sortBy) {
|
||||
$this->data = $data;
|
||||
$this->sortBy = $sortBy;
|
||||
$order = $this->listTree($data, 0, 0);
|
||||
$this->reorder($order[0]);
|
||||
return $this->result;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue