0

我正在尝试添加两个多维数组。该函数应该与将数组添加在一起的方式完全相同,如下所示:$new_array = $array1 + $array2,除了它应该适用于多维数组。这意味着 $array2 不应覆盖现有的键值。

示例:假设我有以下 $default_array:

array
  'something' => int 0
  'nested' => 
    array (size=3)
      'a' => null
      'b' => null
      'c' => null

以及以下 $user_array:

array
  'something' => int 1000
  'nested' => 
    array (size=3)
      'a' => 1
  'new' => int 4

将两者加在一起(如 $user_array + $default_array)应该给我:

array (size=4)
      'something' => int 1000
      'nested' => 
        array (size=3)
          'a' => 1
          'b' => null
          'c' => null
      'new' => int 4

目前,如果我添加两个多维数组,覆盖功能似乎只适用于第一个数组维度。这意味着在这种情况下,'nested' 已经存在于 $user_array 中,因此它不会附加其他值。

编辑:我还应该提到,这需要使用无限量的维度。

编辑 2:我只是尝试应用 Rain 的答案,但它没有按预期工作。首先,我收到“未定义索引”通知。其次,输出不是我想要的。考虑以下数组:

        $default = array(
            'a' => array(
                'a' => 'a',
                'b' => 'b',
                'c' => 'c',
                ),
            );

        $user = array(
            'b' => 1,
            'a' => array(
                'b' => 'something',
                'c' => 'something else',
                'd' => 'd',
                ),
            'c' => 2);

我用 Rain 的函数得到的输出是这样的:

array (size=3)
  'a' => 
    array (size=3)
      'a' => string 'a' (length=1)
      'b' => string 'b' (length=1)
      'c' => string 'c' (length=1)
  'b' => int 1
  'c' => int 2

在此示例中,子数组中的“b”和“c”键应分别为“something”和“something else”。我不太确定如何解决这个问题。

4

3 回答 3

1

您可以尝试使用array_merge_recursive()(不仅仅是array_merge()) http://www.php.net/manual/en/function.array-merge-recursive.php

<?php
$defaultarray = array(
'something' => 0,
  'nested' => 
    array (
      'a' => null,
      'b' => null,
      'c' => null));

$newArray = array(
  'something' => 1000, 
  'nested' => 
    array ('a' => 1,
  'new' => 4));

$mergedArray = array_merge_recursive($defaultarray, $newArray);
echo print_r($mergedArray,true);
?>

输出: Array ( [something] => Array ( [0] => 0 [1] => 1000 ) [nested] => Array ( [a] => Array ( [0] => [1] => 1 ) [b] => [c] => [新] => 4))

于 2013-04-24T23:24:51.803 回答
1

递归函数绝对是这里的方法。我刚刚整理了以下内容。注意&在函数声明中使用fill_in_aux. 这会导致第二个参数(称为$default)通过引用而不是值传递。它被包裹起来,fill_in这样真正的“默认”数组就不会被修改。

function fill_in($user, $default) {
    fill_in_aux($user, $default);
    return $default;
}

function fill_in_aux($user, &$default) {
    foreach ($user as $key => $value) {
        if (is_array($value)) {
            fill_in_aux($user[$key], $default[$key]);
        } else {
            $default[$key] = $value;
        }
    }
}

这假定数组中设置的任何内容都$default应该被数组中存在的任何内容覆盖$user,即使数组中的键$user设置为null。要更改此行为,ifelsefill_in_aux.


示例用法

使用您的示例数组,输出

print_r(fill_in($user_array, $default_array));

Array
(
    [something] => 1000
    [nested] => Array
        (
            [a] => 1
            [b] =>
            [c] =>
        )

    [new] => 4
)

分解

通常,在 PHP 中调用函数时,参数是按传递的:函数获取传入变量的副本。这意味着函数可以对参数执行任何操作,但是当函数返回时,传递的原始变量不受影响。

当参数以&符号开头时,参数通过引用传递,而不是被复制。当函数对参数进行修改时,它实际上是直接对传入的变量进行更改。

有关更多信息,请查看: http: //php.net/manual/en/language.references.pass.php

于 2013-04-24T23:33:01.237 回答
0

令我惊讶的是,array_replace_recursive()七年前没有人为您提供本机功能。@bestprogrammerintheworld 是在正确的轨道上,但选择了错误的递归调用。

使用除此功能之外的任何东西都将是不必要的代码膨胀,并且很可能会降低性能。

代码:(演示

var_export(
    array_replace_recursive($default, $user)
);

输出:

array (
  'a' => 
  array (
    'a' => 'a',
    'b' => 'something',
    'c' => 'something else',
    'd' => 'd',
  ),
  'b' => 1,
  'c' => 2,
)
于 2020-06-30T05:19:22.510 回答