You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP将扁平数组转换为递归菜单式嵌套数组?

用PHP将扁平数组转换为递归嵌套数组

给定如下扁平数组数据(支持扩展更多层级):

[
    [
        "id" => "uuid-1",
        "createdAt" => "2021-02-26T00:55:36.632Z",
        "name" => "Webprovise Corp",
        "parentId" => "0"
    ],
    [
        "id" => "uuid-2",
        "createdAt" => "2021-02-25T10:35:32.978Z",
        "name" => "Stamm LLC",
        "parentId" => "uuid-1"
    ],
    [
        "id" => "uuid-3",
        "createdAt" => "2021-02-25T15:16:30.887Z",
        "name" => "Blanda, Langosh and Barton",
        "parentId" => "uuid-1"
    ],
    [
        "id" => "uuid-4",
        "createdAt" => "2021-02-25T06:11:47.519Z",
        "name" => "Price and Sons",
        "parentId" => "uuid-2"
    ],
    [
        "id" => "uuid-5",
        "createdAt" => "2021-02-25T13:35:57.923Z",
        "name" => "Hane - Windler",
        "parentId" => "uuid-3"
    ],
    [
        "id" => "uuid-6",
        "createdAt" => "2021-02-26T01:41:06.479Z",
        "name" => "Vandervort - Bechtelar",
        "parentId" => "uuid-3"
    ],
    [
        "id" => "uuid-7",
        "createdAt" => "2021-02-25T07:56:32.335Z",
        "name" => "Zieme - Mills",
        "parentId" => "uuid-2"
    ]
]

需要将其转换为包含childrens字段的递归嵌套数组,期望输出格式如下:

[
    "uuid-1" => [
        "id" => "uuid-1",
        "createdAt" => "2021-02-26T00:55:36.632Z",
        "name" => "Webprovise Corp",
        "childrens" => [
            [
                "id" => "uuid-2",
                "createdAt" => "2021-02-25T10:35:32.978Z",
                "name" => "Stamm LLC",
                "parentId" => "uuid-1",
                "childrens" => [
                    [
                        "id" => "uuid-4",
                        "createdAt" => "2021-02-25T06:11:47.519Z",
                        "name" => "Price and Sons",
                        "parentId" => "uuid-2"
                    ],
                    [
                        "id" => "uuid-7",
                        "createdAt" => "2021-02-25T07:56:32.335Z",
                        "name" => "Zieme - Mills",
                        "parentId" => "uuid-2"
                    ]
                ]
            ],
            [
                "id" => "uuid-3",
                "createdAt" => "2021-02-25T15:16:30.887Z",
                "name" => "Blanda, Langosh and Barton",
                "parentId" => "uuid-1",
                "childrens" => [
                    [
                        "id" => "uuid-5",
                        "createdAt" => "2021-02-25T13:35:57.923Z",
                        "name" => "Hane - Windler",
                        "parentId" => "uuid-3"
                    ],
                    [
                        "id" => "uuid-6",
                        "createdAt" => "2021-02-26T01:41:06.479Z",
                        "name" => "Vandervort - Bechtelar",
                        "parentId" => "uuid-3"
                    ]
                ]
            ],
        ]
    ]   
]

解决思路

  • 第一步:将扁平数组转换为以id为键的索引数组,快速通过parentId定位父节点,避免重复遍历查找,提升处理效率。
  • 第二步:遍历所有节点,把每个节点添加到对应父节点的childrens数组中;根节点(parentId为0)直接存入结果数组。
  • 第三步:该逻辑自动支持任意多级子节点,无需额外递归处理,因为父节点的childrens会被持续填充。

实现代码

function buildNestedTree(array $flatArray): array
{
    // 构建以id为键的索引数组,同时初始化每个节点的childrens字段
    $indexed = [];
    foreach ($flatArray as $item) {
        $item['childrens'] = [];
        $indexed[$item['id']] = $item;
    }

    $nestedTree = [];
    foreach ($indexed as $id => $item) {
        $parentId = $item['parentId'];
        if ($parentId === '0') {
            // 根节点直接加入结果集
            $nestedTree[$id] = $item;
        } else {
            // 将当前节点挂载到父节点的childrens数组中
            if (isset($indexed[$parentId])) {
                $indexed[$parentId]['childrens'][] = $item;
            }
        }
    }

    return $nestedTree;
}

// 示例调用
$flatData = [
    ["id" => "uuid-1", "createdAt" => "2021-02-26T00:55:36.632Z", "name" => "Webprovise Corp", "parentId" => "0"],
    ["id" => "uuid-2", "createdAt" => "2021-02-25T10:35:32.978Z", "name" => "Stamm LLC", "parentId" => "uuid-1"],
    ["id" => "uuid-3", "createdAt" => "2021-02-25T15:16:30.887Z", "name" => "Blanda, Langosh and Barton", "parentId" => "uuid-1"],
    ["id" => "uuid-4", "createdAt" => "2021-02-25T06:11:47.519Z", "name" => "Price and Sons", "parentId" => "uuid-2"],
    ["id" => "uuid-5", "createdAt" => "2021-02-25T13:35:57.923Z", "name" => "Hane - Windler", "parentId" => "uuid-3"],
    ["id" => "uuid-6", "createdAt" => "2021-02-26T01:41:06.479Z", "name" => "Vandervort - Bechtelar", "parentId" => "uuid-3"],
    ["id" => "uuid-7", "createdAt" => "2021-02-25T07:56:32.335Z", "name" => "Zieme - Mills", "parentId" => "uuid-2"],
];

$nestedResult = buildNestedTree($flatData);
// 打印格式化后的结果
echo '<pre>' . print_r($nestedResult, true) . '</pre>';

代码说明

  • 先通过一次遍历生成索引数组,给每个节点初始化childrens空数组,后续查找父节点的时间复杂度为O(1),大幅提升效率。
  • 二次遍历完成节点挂载:根节点直接进入结果数组,子节点则添加到对应父节点的childrens中,逻辑清晰且支持无限层级。
  • 采用迭代式处理,避免了递归可能出现的深度限制问题,同时性能更优,适合处理大量数据。

内容的提问来源于stack exchange,提问作者May'Habit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:09:33