Каков эффективный способ поместить данные дерева в массив ?
Я выполнил учебное руководство по сайту, чтобы получить данные дерева.
Однако в учебнике показано только, как выводить дерево, а не как создать многогранный массив.
я использовал
SELECT title, lft, rgt FROM tree_structure WHERE lft BETWEEN $parentLft AND $parentRgt ORDER BY lft ASC
Поэтому для каждого элемента у меня есть его название, левое и правое значения.
Я застрял на том, чтобы массив выглядел так
Array ( Title: Main Topic Children => Array ( => Title: subTopic Leaf: true => Title: Another subtopic Children => Array ( => Title: subtopic child Leaf: true ) ) )
Если бы вы могли помочь, я бы очень признателен.
PS. Вывод sql выглядит так (кроме заголовка, а не имени и не используйте category_id):
+-------------+----------------------+-----+-----+ | category_id | name | lft | rgt | +-------------+----------------------+-----+-----+ | 1 | ELECTRONICS | 1 | 20 | | 2 | TELEVISIONS | 2 | 9 | | 3 | TUBE | 3 | 4 | | 4 | LCD | 5 | 6 | | 5 | PLASMA | 7 | 8 | | 6 | PORTABLE ELECTRONICS | 10 | 19 | | 7 | MP3 PLAYERS | 11 | 14 | | 8 | FLASH | 12 | 13 | | 9 | CD PLAYERS | 15 | 16 | | 10 | 2 WAY RADIOS | 17 | 18 |
Сделайте этот код выстрелом. $ results – результаты базы данных. $ tree – массив, который вы возвращаете.
function create_tree ($results) { $return = $results[0]; array_shift($results); if ($return['lft'] + 1 == $return['rgt']) $return['leaf'] = true; else { foreach ($results as $key => $result) { if ($result['lft'] > $return['rgt']) //not a child break; if ($rgt > $result['lft']) //not a top-level child continue; $return['children'][] = create_tree(array_values($results)); foreach ($results as $child_key => $child) { if ($child['rgt'] < $result['rgt']) unset($results[$child_key]); } $rgt = $result['rgt']; unset($results[$key]); } } unset($return['lft'],$return['rgt']); return $return; } $tree = create_tree($results);
неfunction create_tree ($results) { $return = $results[0]; array_shift($results); if ($return['lft'] + 1 == $return['rgt']) $return['leaf'] = true; else { foreach ($results as $key => $result) { if ($result['lft'] > $return['rgt']) //not a child break; if ($rgt > $result['lft']) //not a top-level child continue; $return['children'][] = create_tree(array_values($results)); foreach ($results as $child_key => $child) { if ($child['rgt'] < $result['rgt']) unset($results[$child_key]); } $rgt = $result['rgt']; unset($results[$key]); } } unset($return['lft'],$return['rgt']); return $return; } $tree = create_tree($results);
неfunction create_tree ($results) { $return = $results[0]; array_shift($results); if ($return['lft'] + 1 == $return['rgt']) $return['leaf'] = true; else { foreach ($results as $key => $result) { if ($result['lft'] > $return['rgt']) //not a child break; if ($rgt > $result['lft']) //not a top-level child continue; $return['children'][] = create_tree(array_values($results)); foreach ($results as $child_key => $child) { if ($child['rgt'] < $result['rgt']) unset($results[$child_key]); } $rgt = $result['rgt']; unset($results[$key]); } } unset($return['lft'],$return['rgt']); return $return; } $tree = create_tree($results);
сfunction create_tree ($results) { $return = $results[0]; array_shift($results); if ($return['lft'] + 1 == $return['rgt']) $return['leaf'] = true; else { foreach ($results as $key => $result) { if ($result['lft'] > $return['rgt']) //not a child break; if ($rgt > $result['lft']) //not a top-level child continue; $return['children'][] = create_tree(array_values($results)); foreach ($results as $child_key => $child) { if ($child['rgt'] < $result['rgt']) unset($results[$child_key]); } $rgt = $result['rgt']; unset($results[$key]); } } unset($return['lft'],$return['rgt']); return $return; } $tree = create_tree($results);
Я бы начал с перезаписи SQL-запроса на это:
SELECT title, (SELECT TOP 1 title FROM tree t2 WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt ORDER BY t2.rgt-t1.rgt ASC) AS parent FROM tree t1 ORDER BY rgt-lft DESC
Это даст вам результат следующим образом:
title | parent ---------------------------------------------- ELECTRONICS | NULL PORTABLE ELECTRONICS | ELECTRONICS TELEVISIONS | ELECTRONICS MP3 PLAYERS | PORTABLE ELECTRONICS FLASH | MP3 PLAYERS CD PLAYERS | PORTABLE ELECTRONICS 2 WAY RADIOS | PORTABLE ELECTRONICS TUBE | TELEVISIONS LCD | TELEVISIONS PLASMA | TELEVISIONS
При этом это намного проще.
используя create_tree, я получил ошибку на этом этапе:
if ($rgt > $result['lft']) //not a top-level child continue;
Ошибка, которую он возвращает, говорит: Неопределенная переменная: rgt
Также он не вернул правильное количество массива ….. Я использую ту же структуру базы данных в
http://articles.sitepoint.com/article/hierarchical-data-database/2