【问题标题】:Generate Nested Tree Structure or Hierarchy based on parent child relationship using recursion - PHP使用递归基于父子关系生成嵌套树结构或层次结构 - PHP
【发布时间】:2021-02-02 10:39:20
【问题描述】:

从昨天开始,我一直被困在这个问题上,任何帮助都将不胜感激。情况是这样的:我有一个具有以下结构的导航链接表, 编号 | parent_id |文字

在我的场景中,parent_id 可能为 null(无子菜单)或任何指向表的 id,这将使记录成为父级的子菜单。我尝试了许多不同的方法来执行此操作,但没有运气,我想出的最接近的方案如下,

// All navigation link results are stored in $data
public static function transform(array &$data) {
    $result = [];
    $search = function(&$array = [], $parent = null) use (&$search, &$result){
        foreach($array as $key => $value) {
            /** If the element has an ancestor */
            if($parent && $parent->id == $value->parent_id) {
                $next = $parent->children[] = $value;
                $search($array, $next);
                unset($array[$key]);
            }
        }

        return $parent;
    };

    foreach($data as $val) {
        $result[] = $search($data, $val);
    }
    return $result;
}

该函数工作正常并跟踪某个链接的所有祖先,但在下一次迭代中跟踪下一个元素的所有祖先(即使它是前一个元素的子元素),因此它返回了很多重复的数据。我想出了从数组中取消设置迭代元素的解决方案,但由于某种原因,该元素仍在下一次迭代中使用。 Here is my current data

Here is my current result

【问题讨论】:

  • 它可能只需要在递归位之前有unset($array[$key]);(所以在$search($array, $next);之前移动它)
  • 返回的结果完全相同。

标签: php recursion multidimensional-array


【解决方案1】:

一个用于更快搜索和只处理一个项目一次的简单概念。

  • 使用key as idvalues as array of child ids 创建一个临时数组。将使用此数组来处理下一个直接子代。这将是深度优先遍历。
  • 同样在输入数组中设置id作为key,这样我们可以在需要的时候直接访问整个节点。
function generateTree($data){
    $arrChild = [];   // Store parent as key and its childs as array to quickly find out.
    foreach($data as $obj){
        $arrChild[$obj->parent_id][] = $obj->id;
        $data[$obj->id] = $obj;
    }
    
    $final = [];
    
    $setChild = function(&$array, $parents) use (&$setChild, $data, $arrChild){
        foreach($parents as $parent){
            $temp = $data[$parent];
            // If key is set, that means given node has direct childs, so process them too.
            if(isset($arrChild[$parent])){
                $temp->children = [];
                $setChild($temp->children, $arrChild[$parent]);
            }
            $array[] = $temp;
        }    
    };
    // Empty key would represent nodes with parent as `null`
    $setChild($final, $arrChild['']);
    return $final;
}

$final = generateTree($arr);

echo json_encode($final, JSON_PRETTY_PRINT);

输出:

[
    {
        "id": 1,
        "navigation_id": 4,
        "parent_id": null,
        "text": "link 1",
        "icon": "",
        "url": null,
        "page_id": 4,
        "children": [
            {
                "id": 2,
                "navigation_id": 4,
                "parent_id": 1,
                "text": "link 2",
                "icon": "",
                "url": null,
                "page_id": 4,
                "children": [
                    {
                        "id": 3,
                        "navigation_id": 4,
                        "parent_id": 2,
                        "text": "link 3",
                        "icon": "fas fa-ad",
                        "url": "https:\/\/google.com",
                        "page_id": null
                    },
                    {
                        "id": 4,
                        "navigation_id": 4,
                        "parent_id": 2,
                        "text": "link 4",
                        "icon": "fab fa-google",
                        "url": "https:\/\/google.com",
                        "page_id": null
                    }
                ]
            }
        ]
    },
    {
        "id": 5,
        "navigation_id": 4,
        "parent_id": null,
        "text": "link 5",
        "icon": "",
        "url": null,
        "page_id": 5,
        "children": [
            {
                "id": 6,
                "navigation_id": 4,
                "parent_id": 5,
                "text": "link 6",
                "icon": "",
                "url": null,
                "page_id": 4
            },
            {
                "id": 7,
                "navigation_id": 4,
                "parent_id": 5,
                "text": "link 7",
                "icon": "",
                "url": null,
                "page_id": 4
            }
        ]
    }
]

【讨论】:

  • 非常感谢!我没有想过为处理后的数据使用临时存储,现在我看到了我的问题的解决方案。
猜你喜欢
  • 2021-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2019-12-20
相关资源
最近更新 更多