我试图添加两个多维数组。该函数应该与将数组相加完全相同,如下所示:$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'。我不太确定如何解决这个问题
您可以尝试使用 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);
?>
输出:数组([一些]=>数组([0]=> 0[1]=> 1000)(嵌套的)=>数组([a] =>数组([0]=> [1]=> 1)[b] => [c] =>[新]=> 4))
递归函数在这里绝对是可行的。我刚刚做了下面这些。注意在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
。要更改此行为,请在fill_in_aux
的else
子句中添加另一个if
语句。
对于您的示例数组,
的输出print_r(fill_in($user_array, $default_array));
print_r(fill_in($user_array, $default_array));
Array
(
[something] => 1000
[nested] => Array
(
[a] => 1
[b] =>
[c] =>
)
[new] => 4
)
分解
通常,在PHP中调用函数时,参数是通过value传递的:函数获取传入变量的副本。这意味着函数可以对参数做任何它想做的事情,但是当函数返回时,传递的原始变量不受影响。
当参数以&
符号开头时,参数通过引用传递,而不是被复制。当函数对形参进行修改时,实际上是直接对传入的变量进行修改。
更多信息,请查看:http://php.net/manual/en/language.references.pass.php
我很惊讶七年前没有人提供原生函数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,
)