使用array_merge丢失值

时间:2014-09-01 22:11:21

标签: php arrays array-merge

我有一个数组:

{
  "zone1":{
    "foo1":"bar1",
    "foo2":"bar2",
    "foo3":"bar3",
    "foo4":"bar4"
  },
  "zone2":{
    "newfoo1":"newbar1",
    "newfoo2":"newbar2",
    "newfoo3":"newbar3",
    "newfoo4":"newbar4"
  },
  "zone3":{
    "morefoo1":"morebar1",
    "morefoo2":"morebar2",
    "morefoo3":"morebar3",
    "morefoo4":"morebar4"
  }
}

我想将第二个数组与更新的值合并:

{
  "zone1":{
    "foo1":"updatedbar1"
  },
  "zone3":{
    "morefoo2":"updatedbar2",
    "morefoo4":"updatedbar4"
  }
}

我尝试了很多东西,我现在使用的是这个PHP代码:

$array3 = array_merge($array1, $array2);

但是这段代码给了我这个:

{
  "zone1":{
    "foo1":"updatedbar1"
  },
  "zone2":{
    "newfoo1":"newbar1",
    "newfoo2":"newbar2",
    "newfoo3":"newbar3",
    "newfoo4":"newbar4"
  },
  "zone3":{
    "morefoo2":"updatedbar2",
    "morefoo4":"updatedbar4"
  }
}

我想要的只是使用第二个数组上的值更新第一个数组,而不会丢失任何数据。 数组是json,它们来自json文件,但语言是PHP。

2 个答案:

答案 0 :(得分:4)

您可以使用array_replace_recursive()

$array3 = array_replace_recursive($array1, $array2);

它使用您的数据创建以下数组:

Array
(
    [zone1] => Array
        (
            [foo1] => updatedbar1
            [foo2] => bar2
            [foo3] => bar3
            [foo4] => bar4
        )

    [zone2] => Array
        (
            [newfoo1] => newbar1
            [newfoo2] => newbar2
            [newfoo3] => newbar3
            [newfoo4] => newbar4
        )

    [zone3] => Array
        (
            [morefoo1] => morebar1
            [morefoo2] => updatedbar2
            [morefoo3] => morebar3
            [morefoo4] => updatedbar4
        )

)

ideone上查看。

答案 1 :(得分:0)

array_merge()只合并顶级数组,并没有考虑数组内的数组。因此,后一个数组将覆盖重复的值。

您可以使用array_merge_recursive()

解决此问题
$ar1 = array("color" => array("favorite" => "red"), 5);
$ar2 = array(10, "color" => array("favorite" => "green", "blue"));
$result = array_merge_recursive($ar1, $ar2);

可以在php.net page

上找到更多信息

- 的修改

上面提到的页面上的第一条评论解释了如何合并两个数组,而使用第二个数组更新第一个数组:

<?php
/**
* array_merge_recursive does indeed merge arrays, but it converts values with duplicate
* keys to arrays rather than overwriting the value in the first array with the duplicate
* value in the second array, as array_merge does. I.e., with array_merge_recursive,
* this happens (documented behavior):
*
* array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
*     => array('key' => array('org value', 'new value'));
*
* array_merge_recursive_distinct does not change the datatypes of the values in the     arrays.
* Matching keys' values in the second array overwrite those in the first array, as is     the
* case with array_merge, i.e.:
*
* array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
*     => array('key' => array('new value'));
*
* Parameters are passed by reference, though only for performance reasons. They're     not
* altered by this function.
*
* @param array $array1
* @param array $array2
* @return array
* @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
* @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
*/
function array_merge_recursive_distinct ( array &$array1, array &$array2 )
{
  $merged = $array1;

  foreach ( $array2 as $key => &$value )
  {
    if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) )
    {
      $merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
    }
    else
    {
  $merged [$key] = $value;
    }
  }

  return $merged;
}
?>
相关问题