合并并覆盖两个或多个多维数组

时间:2012-07-30 03:22:38

标签: php multidimensional-array overwrite array-merge

如何使用array_merge_recursive合并和覆盖具有相同键和值的多维数组?假设我有两个数组如下:

$arr1 = array(       
   // OVERWRITE
   array('prop_id' => 1, 'prop_value' => 'batman'),
   array('prop_id' => 2, 'prop_value' => 'ironman'),
   // NOT OVERWRITE
   array('prop_id' => 5, 'prop_value' => 'wonderwoman'),
);

$arr2 = array(
   array('prop_id' => 1, 'prop_value' => 'robin'),
   array('prop_id' => 2, 'prop_value' => 'superman'),
   array('prop_id' => 4, 'prop_value' => 'catwoman'),
);

我想合并并用新值覆盖它(规则是比较键,它具有不覆盖的相同值),预期结果是

 $result = array_merge_overwrite($arr1, $arr2, array('prop_id') /* Comparison Key */);
 $result = array(       
   array('prop_id' => 1 /* Comparison Key */, 'prop_value' => 'robin' /* Comparison value */),
   array('prop_id' => 2, 'prop_value' => 'superman'),
   array('prop_id' => 4, 'prop_value' => 'catwoman'),
   array('prop_id' => 5, 'prop_value' => 'wonderwoman'),
);

使用array_merge_recursive,它不会被覆盖,我尝试使用如下的array_replace_recursive:

$result = array_replace_recursive(
    array(
       1 => array('prop_id' => 1, 'prop_value' => 'batman'),
       2 => array('prop_id' => 2, 'prop_value' => 'ironman'),
       5 => array('prop_id' => 5, 'prop_value' => 'wonderwoman'),
    ),
    array(
       1 => array('prop_id' => 1, 'prop_value' => 'robin'),
       2 => array('prop_id' => 2, 'prop_value' => 'superman'),
       4 => array('prop_id' => 4, 'prop_value' => 'catwoman'),
    ),
);

它有效,但我的代码看起来很讨厌和肮脏。比我的更好的解决方案

2 个答案:

答案 0 :(得分:1)

这是一个可以按照你所描述的那样运作的函数:

function array_merge_overwrite($arr1, $arr2, $uniques=array('prop_id'), $delimiter='-')
{
    $result = array();
    $uk = array();
    foreach($arr1 as $a1)
    {   
        $uk = array();
        foreach($uniques as $u) $uk[] = $a1[$u];
        $result[implode($delimiter, $uk)] = $a1;
    }   

    foreach($arr2 as $a2)
    {   
        $uk = array();
        foreach($uniques as $u) $uk[] = $a2[$u];
        $result[implode($delimiter, $uk)] = $a2;
    }   
    return $result;
}

如果问题中定义了$arr1$arr2,则上面的函数将返回一个数组:

Array
(
    [1] => Array
        (
            [prop_id] => 1
            [prop_value] => robin
        )

    [2] => Array
        (
            [prop_id] => 2
            [prop_value] => superman
        )

    [5] => Array
        (
            [prop_id] => 5
            [prop_value] => wonderwoman
        )

    [4] => Array
        (
            [prop_id] => 4
            [prop_value] => catwoman
        )

)

当然,如果你总是只使用prop_id作为唯一元素,那么函数可能会更简单:

function array_merge_overwrite($arr1, $arr2)
{
    $tmp = array();
    foreach($arr1 as $a1) $tmp[$a1['prop_id']] = $a1['prop_value'];
    foreach($arr2 as $a2) $tmp[$a2['prop_id']] = $a2['prop_value'];
    $result = array();
    foreach($tmp as $k=>$v) $result[] = array('prop_id'=>$k, 'prop_value'=>$v);
    return $result;
}

后一个函数中返回数组的唯一区别是元素数组的键将是标准数值而不是匹配prop_id s

答案 1 :(得分:0)

我可以看到你想保留第二个数组元素,以防第一个数组和第二个数组的键匹配。

PHP手册说: 如果要将第二个数组中的数组元素追加到第一个数组而不覆盖第一个数组中的元素而不重新编制索引,请使用+ array union运算符:

<?php
$array1 = array(0 => 'zero_a', 2 => 'two_a', 3 => 'three_a');
$array2 = array(1 => 'one_b', 3 => 'three_b', 4 => 'four_b');
$result = $array1 + $array2;
var_dump($result);
?> 

将保留第一个数组中的键。如果两个数组中都存在数组键,则将使用第一个数组中的元素,并忽略第二个数组中匹配键的元素。

O / P

array(5) {
  [0]=>
  string(6) "zero_a"
  [2]=>
  string(5) "two_a"
  [3]=>
  string(7) "three_a"
  [1]=>
  string(5) "one_b"
  [4]=>
  string(6) "four_b"
}

有关详细信息,请查看here