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

PHP按相同ID合并两个多维数组的实现问题

解决按ID合并嵌套数组的问题

我来帮你搞定这个嵌套数组按ID合并的需求!核心问题是要以arr1的结构/顺序为基准,用arr2里对应ID的补充数据填充,同时递归处理所有嵌套的children节点。你之前的代码问题主要出在递归逻辑错误,以及没有高效地通过ID匹配元素,下面是具体的解决思路和代码:

关键思路

  1. 先构建ID映射表:把arr2转换成以id为键的关联数组,这样可以O(1)时间找到对应ID的元素,避免每次循环遍历arr2,效率更高,也更清晰。
  2. 递归填充节点:遍历arr1的每个节点,用ID映射表找到对应的数据补充字段,然后递归处理该节点的children(如果有的话)。

完整代码实现

function mergeArrays($arr1, $arr2) {
    // 第一步:构建arr2的ID映射表,快速查找对应ID的元素
    $idMap = [];
    // 辅助函数:递归遍历arr2的所有节点,加入映射表
    $buildIdMap = function($items) use (&$idMap, &$buildIdMap) {
        foreach ($items as $item) {
            $idMap[$item['id']] = $item;
            // 递归处理嵌套的children
            if (isset($item['children']) && is_array($item['children'])) {
                $buildIdMap($item['children']);
            }
        }
    };
    $buildIdMap($arr2);

    // 第二步:递归处理arr1的节点,填充补充数据
    $processNode = function($node) use (&$idMap, &$processNode) {
        // 匹配对应ID的arr2数据,合并字段(保留arr1原有结构)
        if (isset($idMap[$node['id']])) {
            $node = array_merge($node, $idMap[$node['id']]);
        }
        // 递归处理当前节点的children
        if (isset($node['children']) && is_array($node['children'])) {
            $node['children'] = array_map($processNode, $node['children']);
        }
        return $node;
    };

    // 批量处理arr1的所有根节点
    return array_map($processNode, $arr1);
}

// 测试示例数据
$arr1 = [
    [
        "id" => "24",
        "children" => [
            [
                "id" => "21",
                "children" => [["id" => "15"]]
            ]
        ]
    ]
];

$arr2 = [
    ["id" => "24", "name" => " x", "time" => "0", "status" => "0"],
    [
        "id" => "21",
        "children" => [["id" => "15", "name" => "x", "time" => "0", "status" => "0"]],
        "name" => "x", "time" => "0", "status" => "0"
    ]
];

$arr3 = mergeArrays($arr1, $arr2);
print_r($arr3);

代码解释

  • ID映射表构建:用递归辅助函数buildIdMap遍历arr2的所有节点(包括嵌套的children),把每个节点按id存入$idMap,后续查找对应ID的元素只需直接取键值,效率大幅提升。
  • 递归节点处理:processNode函数负责单个节点的填充:先合并当前ID对应的arr2数据(array_merge会保留arr1原有结构,同时添加/覆盖arr2的字段),再递归处理该节点的children数组。
  • array_map批量处理:用array_map批量处理arr1的根节点和每个children数组,代码更简洁易读。

你之前代码的问题分析

  1. 递归调用错误:你之前的递归调用是merge($arr1, $arr2),这会重新处理整个arr1数组,而非当前节点的children,导致逻辑混乱。
  2. ID匹配效率低:每次循环遍历arr2找对应ID,数据量大时性能差且容易出错。
  3. 节点判断不准确:is_array($value)判断太宽泛,应该专门判断是否存在children键且为数组。

运行上面的代码,就能得到你期望的嵌套完整数据的输出啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:55