我有一些代码,似乎使用+=
将两个数组的数据合并,但它并未包含所有元素。这是如何工作的?
示例:
$test = array('hi');
$test += array('test', 'oh');
var_dump($test);
输出:
array(2) {
[0]=>
string(2) "hi"
[1]=>
string(2) "oh"
}
在PHP中,当对数组使用+
运算符时,它代表什么意思?
我有一些代码,似乎使用+=
将两个数组的数据合并,但它并未包含所有元素。这是如何工作的?
示例:
$test = array('hi');
$test += array('test', 'oh');
var_dump($test);
输出:
array(2) {
[0]=>
string(2) "hi"
[1]=>
string(2) "oh"
}
在PHP中,当对数组使用+
运算符时,它代表什么意思?
+ 运算符返回将右侧数组附加到左侧数组的结果;对于两个数组中存在的键,元素来自左侧数组,右侧数组中匹配的元素将被忽略。
如果您执行以下操作:
$array1 = ['one', 'two', 'foo' => 'bar'];
$array2 = ['three', 'four', 'five', 'foo' => 'baz'];
print_r($array1 + $array2);
你将会得到
Array
(
[0] => one // preserved from $array1 (left-hand array)
[1] => two // preserved from $array1 (left-hand array)
[foo] => bar // preserved from $array1 (left-hand array)
[2] => five // added from $array2 (right-hand array)
)
所以+
的逻辑与以下代码段等效:
$union = $array1;
foreach ($array2 as $key => $value) {
if (false === array_key_exists($key, $union)) {
$union[$key] = $value;
}
}
如果您对C级别实现的详细信息感兴趣,请前往
请注意,+
与array_merge()
如何合并数组不同:
print_r(array_merge($array1, $array2));
会给你
Array
(
[0] => one // preserved from $array1
[1] => two // preserved from $array1
[foo] => baz // overwritten from $array2
[2] => three // appended from $array2
[3] => four // appended from $array2
[4] => five // appended from $array2
)
请参考链接页面获取更多示例。
+
和 array_merge
都在底层调用了 zend_hash_merge
。这也是预期的,因为在 PHP 中,数组被实现为有序哈希映射。 - bishop+
和array_merge
函数的行为是反常且不直观的。它们的使用方式与一个简单的英语理解下“添加”或“合并”数组的操作相反。其他语言/库使用+
来连接列表(例如Python中),“merge”函数用于将一个对象的键/值对添加到另一个对象中(例如lodash中)。然而,在PHP中,情况正好相反;array_merge
可用于连接类似列表的数组,但+
不能。与array_merge
不同,+
始终执行任何其他语言中所称的“merge”的操作。 - Mark Amery$user_vars = array("username"=>"John Doe");
$default_vars = array("username"=>"Unknown", "email"=>"no-reply@domain.com");
$config = $user_vars + $default_vars;
$default_vars
是默认值数组,$user_vars
数组将覆盖在$default_vars
中定义的值。在$user_vars
中缺失的值现在是从$default_vars
中获取的默认变量。print_r
的形式打印出来:Array(2){
"username" => "John Doe",
"email" => "no-reply@domain.com"
}
小心处理数字键,如果它们需要保留或者你不想丢失任何内容。
$a = array(2 => "a2", 4 => "a4", 5 => "a5");
$b = array(1 => "b1", 3 => "b3", 4 => "b4");
联合
print_r($a+$b);
Array
(
[2] => a2
[4] => a4
[5] => a5
[1] => b1
[3] => b3
)
print_r(array_merge($a, $b));
Array
(
[0] => a2
[1] => a4
[2] => a5
[3] => b1
[4] => b3
[5] => b4
)
这个操作符将两个数组合并为一个(与array_merge相同,但是使用array_merge时重复的键会被覆盖)。
有关数组操作符的文档可以在这里找到。
+
运算符的结果跟 array_replace() 函数相同,但是由于运算符参数顺序颠倒,所以返回的数组也可能顺序不同。$array1 = array('one', 'two', 'foo' => 'bar');
$array2 = array('three', 'four', 'five', 'foo' => 'baz');
print_r($array1 + $array2);
print_r(array_replace($array2, $array1)); //note reversed argument order
输出:
Array
(
[0] => one // preserved from $array1
[1] => two // preserved from $array1
[foo] => bar // preserved from $array1
[2] => five // added from $array2
)
Array
(
[0] => one // preserved from $array1
[1] => two // preserved from $array1
[2] => five // added from $array2
[foo] => bar // preserved from $array1
)
+
的顺序是否被规格保证?array_replace
呢? - Pacerier
- 数组加法操作将所有数组视为关联数组。
- 在加法过程中,若键名冲突,则保留左侧(之前的)值。
我在下面发布代码以使事情更清晰。
$a + $b = array_plus($a, $b)
function array_plus($a, $b){
$results = array();
foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
return $results;
}
话虽如此,我们可以认为 + 运算符有点多余,因为使用 array_replace 函数也可以实现相同的效果。
但是,在某些情况下,它非常方便:比如说你有一个 $options 数组被传递给一个函数/方法,还有默认值作为后备:
// we could do it like this
function foo(array $options)
{
$defaults = ['foo' => 'bar'];
$options = array_replace($defaults, $options);
// ...
}
// but + here might be way better:
function foo(array $options)
{
$options += ['foo' => 'bar'];
// ...
}
$var1 = "example";
$var2 = "test";
$output = array_merge((array)$var1,(array)$var2);
print_r($output);
数组([0] => 示例 [1] => 测试)
+=
,而被接受的答案使用了+
。根据我的测试,它们的行为似乎是相同的。 - user151841array_merge
来完成感到有些恐惧吗?这就好像数组默认是关联数组,而数值数组则是二等公民一样。 - icc97