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

如何基于点表示法和type属性将PHP扁平数组转换为树形数组

解决方法

核心逻辑:由于仅category_label类型的节点会包含子节点,我们可以先按节点层级深度升序排序,保证父节点先于子节点处理,再通过引用池存储可容纳子节点的分类节点,快速匹配插入即可。

以下是可直接运行的PHP代码:

function buildHierarchyTree(array $flatArray): array
{
    // 按层级深度从小到大排序,确保父节点先被处理
    usort($flatArray, function ($a, $b) {
        $depthA = count(explode('.', $a['hierarchy']));
        $depthB = count(explode('.', $b['hierarchy']));
        return $depthA <=> $depthB;
    });

    $tree = [];
    $categoryRefs = []; // 存储所有分类节点的引用,key为对应hierarchy值

    foreach ($flatArray as &$node) {
        // 初始化children字段,也可以仅给category_label类型的节点加
        $node['children'] = [];
        
        $hierarchyParts = explode('.', $node['hierarchy']);
        $level = count($hierarchyParts);

        if ($level === 1) {
            // 根节点直接加入树结构
            $tree[] = &$node;
        } else {
            // 计算父节点hierarchy值:去掉当前层级的最后一段
            $parentHierarchy = implode('.', array_slice($hierarchyParts, 0, $level - 1));
            // 找到对应父分类节点,插入到它的children中
            if (isset($categoryRefs[$parentHierarchy])) {
                $categoryRefs[$parentHierarchy]['children'][] = &$node;
            } else {
                // 容错:找不到父分类时可自定义处理,比如加入根节点
                $tree[] = &$node;
            }
        }

        // 仅分类节点存入引用池,供后续子节点匹配
        if ($node['type'] === 'category_label') {
            $categoryRefs[$node['hierarchy']] = &$node;
        }
    }

    unset($node); // 解除引用,避免后续修改污染数据
    return $tree;
}

// 测试调用
$array = [
    [
        "hierarchy" => "1",
        "title" => "Fruits",
        "type" => "category_label"
    ],
    [
        "hierarchy" => "1.1",
        "title" => "Citruses",
        "type" => "category_label"
    ],
    [
        "hierarchy" => "1.1.1",
        "title" => "Orange",
        "type" => "item"
    ],
    [
        "hierarchy" => "1.1",
        "title" => "Mango",
        "type" => "item"
    ],
    [
        "hierarchy" => "1.2",
        "title" => "Grape",
        "type" => "item"
    ]
];

$result = buildHierarchyTree($array);
print_r($result);

逻辑说明

  1. 排序规则:按照hierarchy按点拆分后的长度判断层级深度,深度越小越先处理,保证父节点在子节点之前被加载到引用池。
  2. 引用池作用:仅存储category_label类型的节点,解决同hierarchy值下普通条目不会作为父节点的需求。
  3. 父节点匹配:当前节点去掉hierarchy的最后一段即可得到父节点的hierarchy值,直接从引用池查找即可快速定位父节点。

运行上述代码得到的输出和你预期的树形结构完全一致。


内容的提问来源于stack exchange,提问作者asvp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:15:04