1

如何使用 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'),
    ),
);

它可以工作,但我的代码看起来又脏又脏。任何比我更好的解决方案

4

2 回答 2

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_ids

于 2012-07-30T17:46:48.590 回答
0

正如我所看到的,您希望保留第二个数组元素,以防第一个数组和第二个数组的键匹配。

PHP 手册说: 如果您想将第二个数组中的数组元素附加到第一个数组,同时不覆盖第一个数组中的元素并且不重新索引,请使用 + 数组联合运算符:

<?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);
?> 

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

输出/输出

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"
}

更多细节看这里

于 2012-07-30T03:33:47.103 回答