从平面数组创建一棵树

时间:2021-02-12 16:36:13

标签: php algorithm tree

我在转换平面数组时遇到问题,例如从一个数据库查询到一个树结构。 我有这样的事情:

[
  [ 
    id => 11,
    path => '/11',
    label => 'AAA'
  ],
  [ 
    id => 12,
    path => '/12',
    label => 'BBB'
  ],
  [ 
    id => 21,
    path => '/12/21',
    label => 'BBBB'
  ],
  [ 
    id => 21,
    path => '/12/22',
    label => 'CCCCC'
  ],
]

path 指向树内的分层位置,由 id 定义。所以最后我必须得到这样的东西:

$tree=[
        [
            'id' => '11',
            'label' =>  'AAA'
        ],
        [
            'id' => '12',
            'label' =>  'BBB',
            'children' => [
                [
                    'id' => '21',
                    'label' =>  'BBBB'
                ],
                [
                    'id' => '22',
                    'label' =>  'CCCCC'
                ]
            ]
        ]
    ];

深度可以是无限的。我将不胜感激任何解决方案。谢谢:-)

1 个答案:

答案 0 :(得分:0)

谢谢大家,但我还是被卡住了:-(这是我目前的方法。

首先,我按深度对类别进行排序并按此顺序循环它们。这样我就可以确定父节点存在。

    public function buildCategoryTree() {
        // order by depth
        $categoryLevel = [];
        foreach (Category::all() as $category) {
            $catPathSplitted = array_filter(explode("/", $category->path));
            $categoryLevel[count($catPathSplitted)][] = $category;
        }

        $categoryTree = [];

        // now loop each level and create a tree node
        foreach ($categoryLevel as $level => $categories) {
            foreach ($categories as $category) {
                $test = $category->path;
                $catPathSplitted = array_filter(explode("/", $category->path));
                $categoryTree = $this->addNode($category, $catPathSplitted, $categoryTree, $test);
            }
        }        
    } 

然后我尝试使用这种递归,但它只能部分起作用,这意味着我按层次顺序获取子节点, 但是在每个级别上也会再次创建子节点。所以有问题:-(

    private function addNode($cat, $keys, &$tree) {
        foreach ($keys as $counter => $id) {
            if (!next($keys)) {
                if (!isset($tree[$id]['category'])) {
                    $tree[$id]['category'] = $cat->toArray();
                }
            } else {
                if (!isset($tree[$id]['children'])) {
                    $tree[$id]['children'] = [];
                }
                array_shift($keys);
                $this->addNode($cat, $keys, $tree[$id]['children'], $test);

            }
        }
        return $tree;
    }

有人能发现这个缺陷吗?

相关问题