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

PHP中合并未知键与深度的多维数组并去除重复元素的方法

解决多维数组合并并去重的问题(未知键名和深度)

你的问题很典型——PHP自带的数组合并函数在处理未知深度的多维数组+子元素去重时确实不太好用,咱们来一步步解决:

为什么现有方法失效?

  • array_merge_recursive:只会递归合并同键的数组,但不会检查子元素是否重复,所以会保留两个{"ort": "rom", "lioc": "inrom"}
  • array_merge + array_unique:因为两个数组的外层键都是hotels,array_merge会直接用第二个数组的hotels覆盖第一个的,之后再去重也救不回丢失的元素,这就是result2只剩两个元素的原因

自定义递归合并去重函数

我们需要写一个递归函数,既能处理任意深度的数组,又能对列表型的子数组(索引数组)去重。核心思路是:

  1. 递归遍历两个数组,合并所有键值对
  2. 遇到列表型数组(键为连续数字)时,将子元素序列化为字符串作为临时键,利用数组键的唯一性去重,再转回原数组格式

代码实现:

function merge_unique_recursive($arr1, $arr2) {
    $merged = $arr1;

    foreach ($arr2 as $key => $value) {
        // 递归处理嵌套数组
        if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
            $merged[$key] = merge_unique_recursive($merged[$key], $value);
        } else {
            // 列表型数组的元素直接追加
            if (is_numeric($key)) {
                $merged[] = $value;
            } else {
                // 关联数组的键直接赋值(如需保留两边关联数组键值,可在此处再递归)
                $merged[$key] = $value;
            }
        }
    }

    // 判断是否为列表型数组,若是则去重
    if (array_keys($merged) === range(0, count($merged) - 1)) {
        $temp = [];
        foreach ($merged as $item) {
            // 用JSON序列化作为临时键,确保子数组完全相同时才去重
            $temp[json_encode($item)] = $item;
        }
        // 重置索引,转回列表型数组
        $merged = array_values($temp);
    }

    return $merged;
}

测试你的案例

把你的测试代码替换成下面的调用:

$test_1 = ' { "hotels" : { "hotel" : [ { "ort": "rom", "lioc": "inrom" }, { "ort": "paris", "lioc": "inpsrisd" }, { "ort": "berlin", "lioc": "inberlin" }, { "ort": "milano", "lioc": "inmilano" }, { "ort": "paris", "lioc": "anotherinpsrisd" }, { "ort": "muc", "lioc": "inmuc" } ] } } ';
$test_2 = ' { "hotels" : { "hotel" : [ { "ort": "rom", "lioc": "inrom" }, { "ort": "beijing", "lioc": "wanda" } ] } } ';
$arr_test1 = json_decode($test_1, TRUE);
$arr_test2 = json_decode($test_2, TRUE);

$final_result = merge_unique_recursive($arr_test1, $arr_test2);
var_dump(json_encode($final_result));

运行后就能得到你想要的预期结果:

{ "hotels" : { "hotel" : [ { "ort": "rom", "lioc": "inrom" }, { "ort": "paris", "lioc": "inpsrisd" }, { "ort": "berlin", "lioc": "inberlin" }, { "ort": "milano", "lioc": "inmilano" }, { "ort": "paris", "lioc": "anotherinpsrisd" }, { "ort": "muc", "lioc": "inmuc" }, { "ort": "beijing", "lioc": "wanda" } ] } }

补充说明

这个函数可以适配任意深度的数组,不管键名是什么:

  • 对于关联数组(字符串键):会递归合并对应键的子数组
  • 对于列表型数组(数字键):会合并所有元素并去重,完全相同的子数组只会保留一个

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:59:08