多维数组递归合并问题

两个数组都是规律的键值,两个数组中相同的键值,如果都是数组,进行合并;有一方不是,由另一方覆盖;原数组的维数不定(需要考虑多维情况);
示例(三维数组合并):

#多维数组合并#
$arrAb = array(
'a1' => array('c1' => 'ABC', 'c4' => 55),
'a3' => 42,
'a7' => array('c3' => 'AAA'),
'a9' => array('c8' => 57, 'c9' => array('d1' => 68, 'd3' => 'DAC'))
);
$arrAc = array(
'a1' => array('c2' => 'ACC', 'c4' => 59),
'a3' => array('c1' => 23),
'a7' => array('c3' => 'AAA', 'c6' => 89),
'a9' => array('c8' => 'BAC', 'c9' => array('d2' => 'DBC', 'd3' => 99))
);

合并后的效果:
Array
(
[a1] => Array
(
[c1] => ABC
[c2] => ACC
[c4] => 59
)

[a3] => Array
(
[c1] => 23
)

[a7] => Array
(
[c3] => AAA
[c6] => 89
)

[a9] => Array
(
[c8] => BAC
[c9] => Array
(
[d1] => 68
[d2] => DBC
[d3] => 99
)

)

)

自己写了一个比较笨的,只实现了二维的合并,相用递归,却没法下手了,请指教!


#递归合并多维数组#
function Merge($arr1 = array(), $arr2 = array())
{
$res = array();
if (is_array($arr1) && is_array($arr2)) {
foreach ($arr1 as $m => $val) {
if (is_array($val)) {
if (isset($arr2[$m]) && is_array($arr2[$m])) {
$res[$m] = array_merge($val, $arr2[$m]);
ksort($res[$m]);
} else if ((isset($arr2[$m]) && !is_array($arr2[$m])) || !isset($arr2[$m])) {
$res[$m] = $val;
}
} else {
$res[$m] = $arr2[$m];
}
}
} else if (is_array($arr1) && !is_array($arr2)) {
$res = $arr1;
} else if (!is_array($arr1) && is_array($arr2)) {
$res = $arr2;
}
return $res;
}
$arrMergeRes = Merge($arrAb, $arrAc);
echo 'Merge:<pre>';
print_r($arrMergeRes);
echo '</pre>';
...全文
255 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
oblack_sky 2018-08-30
  • 打赏
  • 举报
回复
楼主你那有写好的函数么, 我也有这种需求,但是是多个多维数组,需要用递归,递归合并, 同一个键只有都为数组的时候合并, 同一个键只要有一方不是数组那么第一个覆盖第二个,
  • 打赏
  • 举报
回复
谢谢版主的帮主,加个排序就完事了,我慢慢消化下
xuzuning 2017-03-05
  • 打赏
  • 举报
回复
丢失数据总是不大妥当的,况且你的规则有点悬:不支持 交换率 但还是可以这样写
$arrAb = array(
    'a1' => array('c1' => 'ABC', 'c4' => 55),
    'a3' => 42,
    'a7' => array('c3' => 'AAA'),
    'a9' => array('c8' => 57, 'c9' => array('d1' => 68, 'd3' => 'DAC'))
);
$arrAc = array(
    'a1' => array('c2' => 'ACC', 'c4' => 59),
    'a3' => array('c1' => 23),
    'a7' => array('c3' => 'AAA', 'c6' => 89),
    'a9' => array('c8' => 'BAC', 'c9' => array('d2' => 'DBC', 'd3' => 99))
);
print_r(Merge($arrAb, $arrAc));

function Merge($a, $b) {
  $n = is_array($a) ? 2 : 0;
  $n += is_array($b) ? 1 : 0;
  switch($n) {
    case 0:
    case 1: return $b;
    case 2: return $a;
  }
  $key = array_merge(array_keys($a), array_keys($b));
  foreach($key as $k) {
    if(isset($a[$k]) && isset($b[$k])) $r[$k] = Merge($a[$k], $b[$k]);
    elseif(isset($a[$k])) $r[$k] = $a[$k];
    else $r[$k] = $b[$k];
  }
  return $r;
}
Array
(
    [a1] => Array
        (
            [c1] => ABC
            [c4] => 59
            [c2] => ACC
        )

    [a3] => Array
        (
            [c1] => 23
        )

    [a7] => Array
        (
            [c3] => AAA
            [c6] => 89
        )

    [a9] => Array
        (
            [c8] => BAC
            [c9] => Array
                (
                    [d1] => 68
                    [d3] => 99
                    [d2] => DBC
                )

        )

)

  • 打赏
  • 举报
回复
谢谢版主的提议,这个我之前试过了,array_merge_recursive是可以递归合并,但是遇到同键值的数组,会合并处理,而不是需求中的同键值后方覆盖前方,如:

$arr1 = array('a1' => 123));
$arr2 = array('a1' => array(546));

$arr = array_merge_recursive($arr1, 'arr2);
//array(123, array(546));
而期待的效果是: array('a1' => array(546));
丰锅神操作 2017-03-04
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
为什么不用 array_merge_recursive 呢? 虽然 array_merge_recursive 的结果和你期望的不一样,但是他不会丢失数据
$arrAb = array(
    'a1' => array('c1' => 'ABC', 'c4' => 55),
    'a3' => 42,
    'a7' => array('c3' => 'AAA'),
    'a9' => array('c8' => 57, 'c9' => array('d1' => 68, 'd3' => 'DAC'))
);
$arrAc = array(
    'a1' => array('c2' => 'ACC', 'c4' => 59),
    'a3' => array('c1' => 23),
    'a7' => array('c3' => 'AAA', 'c6' => 89),
    'a9' => array('c8' => 'BAC', 'c9' => array('d2' => 'DBC', 'd3' => 99))
);

$r = array_merge_recursive($arrAb, $arrAc);
print_r($r);

Array
(
    [a1] => Array
        (
            [c1] => ABC
            [c4] => Array
                (
                    [0] => 55
                    [1] => 59
                )

            [c2] => ACC
        )

    [a3] => Array
        (
            [0] => 42
            [c1] => 23
        )

    [a7] => Array
        (
            [c3] => Array
                (
                    [0] => AAA
                    [1] => AAA
                )

            [c6] => 89
        )

    [a9] => Array
        (
            [c8] => Array
                (
                    [0] => 57
                    [1] => BAC
                )

            [c9] => Array
                (
                    [d1] => 68
                    [d3] => Array
                        (
                            [0] => DAC
                            [1] => 99
                        )

                    [d2] => DBC
                )

        )

)

果然版主是老司机,以后多问你。。我用两个遍历做过。
xuzuning 2017-03-04
  • 打赏
  • 举报
回复
为什么不用 array_merge_recursive 呢? 虽然 array_merge_recursive 的结果和你期望的不一样,但是他不会丢失数据
$arrAb = array(
    'a1' => array('c1' => 'ABC', 'c4' => 55),
    'a3' => 42,
    'a7' => array('c3' => 'AAA'),
    'a9' => array('c8' => 57, 'c9' => array('d1' => 68, 'd3' => 'DAC'))
);
$arrAc = array(
    'a1' => array('c2' => 'ACC', 'c4' => 59),
    'a3' => array('c1' => 23),
    'a7' => array('c3' => 'AAA', 'c6' => 89),
    'a9' => array('c8' => 'BAC', 'c9' => array('d2' => 'DBC', 'd3' => 99))
);

$r = array_merge_recursive($arrAb, $arrAc);
print_r($r);

Array
(
    [a1] => Array
        (
            [c1] => ABC
            [c4] => Array
                (
                    [0] => 55
                    [1] => 59
                )

            [c2] => ACC
        )

    [a3] => Array
        (
            [0] => 42
            [c1] => 23
        )

    [a7] => Array
        (
            [c3] => Array
                (
                    [0] => AAA
                    [1] => AAA
                )

            [c6] => 89
        )

    [a9] => Array
        (
            [c8] => Array
                (
                    [0] => 57
                    [1] => BAC
                )

            [c9] => Array
                (
                    [d1] => 68
                    [d3] => Array
                        (
                            [0] => DAC
                            [1] => 99
                        )

                    [d2] => DBC
                )

        )

)

array_change_key_case -- 返回字符串键名全为小写或大写的数组 array_chunk -- 将一个数组分割成多个 array_combine -- 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值 array_count_values -- 统计数组中所有的值出现的次数 array_diff_assoc -- 带索引检查计算数组的差集 array_diff_key -- 使用键名比较计算数组的差集 array_diff_uassoc -- 用用户提供的回调函数做索引检查来计算数组的差集 array_diff_ukey -- 用回调函数对键名比较计算数组的差集 array_diff -- 计算数组的差集 array_fill -- 用给定的值填充数组 array_filter -- 用回调函数过滤数组中的单元 array_flip -- 交换数组中的键和值 array_intersect_assoc -- 带索引检查计算数组的交集 array_intersect_key -- 使用键名比较计算数组的交集 array_intersect_uassoc -- 带索引检查计算数组的交集,用回调函数比较索引 array_intersect_ukey -- 用回调函数比较键名来计算数组的交集 array_intersect -- 计算数组的交集 array_key_exists -- 检查给定的键名或索引是否存在于数组中 array_keys -- 返回数组中所有的键名 array_map -- 将回调函数作用到给定数组的单元上 array_merge_recursive -- 递归合并一个或多个数组 array_merge -- 合并一个或多个数组 array_multisort -- 对多个数组多维数组进行排序 array_pad -- 用值将数组填补到指定长度 array_pop -- 将数组最后一个单元弹出(出栈) array_product -- 计算数组中所有值的乘积

21,887

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧