【问题标题】:PHP tree depending list only for some childrensPHP树依赖列表仅适用于某些孩子
【发布时间】:2020-08-27 10:04:17
【问题描述】:

我正在寻找一个可以创建分层数组但仅适用于某些孩子的函数。

这个例子似乎不错: Recursive function to generate multidimensional array from database result

但我想要父母只是为了一些 ID。例如:

+-------+---------------+---------------------------+
|   id  |   parent_id   |           title           |
+-------+---------------+---------------------------+
|   1   |       0       |   Parent Page             |
|   2   |       1       |   Sub Page                |
|   3   |       2       |   Sub Sub Page            |
|   4   |       0       |   Another Parent Page     |
|   5   |       1       |   Sub Page 2              |
+-------+---------------+---------------------------+

我只想要 id 2、4 和 5 的层次结构。

然后给我这样的东西:

Array
(
    [0] => Array
        (
            [id] => 1
            [parent_id] => 0
            [title] => Parent Page
            [children] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 2
                                    [parent_id] => 1
                                    [title] => Sub Page                                                    
                                ),
                            [1] => Array
                                (
                                    [id] => 5
                                    [parent_id] => 1
                                    [title] => Sub Page 2                                                     
                                )
                        )
        )
    [1] => Array
        (
            [id] => 4
            [parent_id] => 0
            [title] => Another Parent Page
        )
)

2、4 和 5 应该是最小的孩子,它们下面没有任何东西。

继续,我想要的与链接的帖子完全相同,但我最小的叶子应该只是数组 [2,4,5] 中存在的叶子 id

不知道有没有人理解我的问题...

非常感谢

编辑:我更新并添加了 id = 5 的示例。

【问题讨论】:

    标签: php recursion tree


    【解决方案1】:

    是的,你的问题很清楚。您想从底部到顶部重新创建树,仅针对特定叶子的 id。

    您可以通过从初始数组中过滤掉所有不必要的类别来实现它,然后使用您之前找到的函数构建树。

    //Assuming you have this array with mysql result of all possible categories
    $mysqlRows = [
        ["id" => 1, "parent_id" => 0, "title" => "Parent Page"],
        ["id" => 2, "parent_id" => 1, "title" => "Sub Page"],
        ["id" => 3, "parent_id" => 2, "title" => "Sub Sub Page"],
        ["id" => 4, "parent_id" => 0, "title" => "Another Parent Page"],
        ["id" => 5, "parent_id" => 1, "title" => "Sub Page 2"]
    ];
    
    /*
     * Fill $participatingIds array with id of categories that related to our needs
     * Be aware that $participatingIds has & sign - it means
     * that it will be passed by reference
     */
    function collectAllParentsId($id, $mysqlRows, &$participatingIds)
    {
        if (!in_array($id, $participatingIds)) {
            $participatingIds[] = $id;
        }
        if ($mysqlRows[$id]["parent_id"] !== 0) {
            collectAllParentsId($mysqlRows[$id]["parent_id"], $mysqlRows, $participatingIds);
        }
    }
    
    //Initial function to build a tree from a flat category array
    function buildTree(array $elements, $parentId = 0) {
        $branch = array();
    
        foreach ($elements as $element) {
            if ($element['parent_id'] == $parentId) {
                $children = buildTree($elements, $element['id']);
                if ($children) {
                    $element['children'] = $children;
                }
                $branch[] = $element;
            }
        }
    
        return $branch;
    }
    
    
    /* START */
    
    /*
     * Make array indexes equals to the category's "id",
     * so we can access category like this $mysqlRows[$category_id]
    */
    $mysqlRows = array_column($mysqlRows, null, "id");
    
    //Array of ids for which you want create a tree
    $someIds = [2, 4, 5];
    
    /*
     * Create one flat array with all Ids that will participating in the tree
     * (leaf id and all of it parents id)
     * Order of ids is doesn't matter here
     * $ids will looks like this:
     * [ 1, 2, 4, 5 ]
     */
    
    $ids = [];
    foreach ($someIds as $id) {
        collectAllParentsId($id, $mysqlRows, $ids);
    }
    
    //Now filter out all categories that doesn't participating in out tree
    $filteredRows = array_filter(
        $mysqlRows,
        function ($key) use ($ids) {
            return (in_array($key, $ids));
        },
        ARRAY_FILTER_USE_KEY
    );
    
    //Now we have only desired categories - create the tree from it:
    $tree = buildTree($filteredRows);
    
    var_dump($tree);
    
    

    【讨论】:

    • 您好!非常感谢您的回答!它工作正常,但不完全是我想要的。当我添加一个叶子 ["id" => 5, "parent_id" => 1, "title" => "Sub Page 2 "] 它从 id 1 重新创建一个数组,而不是添加已经创建的数组。在你的情况下,我没有多维数组。看看这个结果的屏幕:casimages.com/i/200827030552125794.png.html你明白我的意思吗?
    • 类似这样的东西:casimages.com/i/200827032524459014.png.html 也许应该更好,但我不知道该怎么做..
    • @MathAng 更简单,看看我更新的解决方案
    • Woo 它似乎工作得很好!我会更新它以适应我的情况!我回头告诉你。我会问我是否有问题哈哈哈非常感谢!你认为这个算法优化了吗?在我的情况下,我有 50.000 行而不是 5 啊啊但更常见的是,只有 3 级层次结构
    • 需要几秒钟才能完成。根据您的服务器功能,有时通过数据库查询找到所有父母 ID 可能会更快。只需进行测试,很有可能当前的解决方案就足够了。
    猜你喜欢
    • 2015-07-03
    • 2020-10-24
    • 2012-05-25
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多