作者hSATAC (cAt Ash)
看板PHP
标题[心得] 阵列相加与 array_merge
时间Tue Nov 6 14:13:24 2012
网页好读:
http://blog.hsatac.net/2012/11/php-array-plus-array-versus-array-merge/
基础观念文,请各位大神自行 end 本文
在 PHP 中 `array + array` 与 `array_merge` 的行为是不一样的,阵列相
加的效能会比 `array_merge` 来的好,但换来的代价是可能不是你预期的行
为以及资料流失。
PHP 的阵列可以有 key 也可以没有 key,也可以两者混合。不过所谓的没有
key ,其实他还是有 key ,只是是自动编上去的 int 流水号 key 例如
0,1,2,3...不管是哪一种,在阵列相加以及 `array_merge` 的行为都不一样
。
先讲一下 `array_merge` 的行为,`array_merge($a, $b)` 的话,如果
`$a` 和 `$b` 里面有 key 相同的元素,则会**後盖前**也就是 `$b` 的值
会盖掉 `$a` 的值。那如果是没有 key (流水号 key)的值,则会以附加在尾
端 (append) 的方式合并上去,而所有流水号 key 的 index 则会重排。
<!--more-->
底下是一个简单的例子:
``` php array_merge
<?php
$arr_a = array('a'=>1, 'b'=>2, 1=>3);
$arr_b = array('b'=>1, 4, 5);
var_dump(array_merge($arr_a, $arr_b));
```
结果为:
```
array(5) {
["a"]=>
int(1)
["b"]=>
int(1)
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(5)
}
```
那如果是 `array + array` 的状况,在有 key 的值的部分是相反的**前盖
後**,而没有 key(流水号 key)的部分也会**前盖後**,流水号 index 不会
重排。我们用同样的例子来观察:
``` php array + array
<?php
$arr_a = array('a'=>1, 'b'=>2, 1=>3);
$arr_b = array('b'=>1, 4, 5);
var_dump($arr_a + $arr_b);
```
结果为:
```
array(4) {
["a"]=>
int(1)
["b"]=>
int(2)
[1]=>
int(3)
[0]=>
int(4)
}
```
由此可知 `array + array` 和 `array_merge` 的行为是完全不一样的,而
大多数的情况阵列相加不会是我们想要的结果。请根据使用状况谨慎选择。
我只有在一个地方使用过阵列相加,在处理使用者设定的部分,系统有一个
预设的设定阵列,使用者也会有使用者自订的设定阵列,而使用者可能只设
了其中几项,这时把这两个阵列相加,就可以组合出一个完整的使用者设定
阵列,使用者没设定的部分就由预设值阵列填补。
``` php
<?php
...
static protected function _fillWithDefault($settings)
{
settype($settings, "array");
$defaults = self::getDefault();
foreach($settings as $key=>$value) {
if(!array_key_exists($key, $defaults))
unset($settings[$key]);
}
return $settings + $defaults;
}
```
当然这个 case 写成 `array_merge($defaults, $settings)` 也是可以达到
一样的效果,不过当时我觉得阵列相加效能较好,语意上也不会造成混淆,
所以就采用这个写法。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 218.211.33.134
1F:推 chrisQQ:原PO高富帅,羡慕给推 11/06 15:52
2F:推 glaci:楼上 XD 推~ 11/06 21:00
3F:推 taikobo:曾经碰到过相关问题,感谢分享^^ 11/07 14:25