0%

合并两个数组有几种方式?试比较它们的异同?

方式:

  1. array_merge()
  2. ‘+’
  3. array_merge_recursive()

补充:以上都是把两个数组合并为一个数组,另外还有一个特殊的合并方式。 array_combine() ,通过合并两个数组来创建一个新数组,其中的一个数组元素为键名,另一个数组元素为键值

实践

接下来我们分析下其每个的具体作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//数组示例1
$a1 = ['a'];
$a2 = ['b'];

echo json_encode(array_merge($a1, $a2)) . "\n";
echo json_encode(array_merge_recursive($a1, $a2)) . "\n";
echo json_encode($a1 + $a2) . "\n";
echo json_encode(array_combine($a1, $a2)) . "\n";
//result ["a","b"]
//result ["a","b"]
//result ["a"]
//result {"a":"b"}

//数组示例2
$b1 = ['a', 'b'];
$b2 = ['b', 'c', 'd'];

echo json_encode(array_merge($b1, $b2))."\n";
echo json_encode(array_merge_recursive($b1, $b2))."\n";
echo json_encode($b1+$b2)."\n";
echo json_encode(array_combine($b1, $b2)) . "\n";
//result ["a","b","b","c","d"]
//result ["a","b","b","c","d"]
//result ["a","b","d"]
// result Warning: array_combine(): Both parameters should have an equal number of elements


//数组示例3
$c1 = ['a' => 1, 'b' => 2];
$c2 = ['b' => 3, 'c' => 4, 'd' => 5];

echo json_encode(array_merge($c1, $c2)) . "\n";
echo json_encode(array_merge_recursive($c1, $c2)) . "\n";
echo json_encode($c1 + $c2) . "\n";
//result {"a":1,"b":3,"c":4,"d":5}
//result {"a":1,"b":[2,3],"c":4,"d":5}
//result {"a":1,"b":2,"c":4,"d":5}

解析

示例1中不难看出array_merge和array_merge_recursive是能正常合并的,不过’+’不行。array_combine前者的元素变成了对应后者元素的键值。

接着示例2,可以看出array_merge和array_merge_recursive依然是能正常合并的。’+’则是合并了后者的第三个元素。array_combine在示例2中则运行报错了。

示例3,array_merge是合并了。array_merge_recursive也合并,若果有相同的键值时,则会递归合并。’+’依然是只合并了后者的第三个元素。

分析得出:

array_merge() ,正常合并两个数组。

array_merge_recursive() ,正常合并两个数组。若果有相同的键值时则递归合并

‘+’ ,根据示例1和示例2对比,我们可以得出键值相同的元素不会附加在前面的数组中,不同则附加,作为结果返回。

array_combine()[进入手册],根据php手册中我们可以找到解释。array_combine(),“创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值.如果作为keys的数组和作为values的数组的元素个数不一样,将会抛出一个警告错误”。

结论

array_merge() 简单的合并数组

array_merge_recursive() 合并两个数组,有相同的键值时则递归合并

‘+’ 合并两个数组,键值相同的元素不会附加在前面的数组中

array_combine() 合并两个数组,前者元素值成了对应后者元素值的键值

后续

细心的小伙伴应该能发现示例2和示例3中array_merge返回值有点不对劲🤔️。

示例2中返回了bb,而示例3只返回了b=>3。

细想了下,若果是键值唯一,那么示例3成立,示例2应是bcd,取后者覆盖后的值。

若果键值不唯一,示例2成立,则示例3应是b=>2,b=>3。

最终查看php手册发现原因,array_merge()[进入手册],“如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值不会 覆盖原来的值,而是附加到后面。”

补充

1
2
3
4
5
6
7
8
9
//数组示例4
$d1 = [ 1 => 'a', 2 => 'b'];
$d2 = [ 3 => 'b', 4 => 'c'];
echo json_encode(array_merge($d1, $d2))."\n";
echo json_encode(array_merge_recursive($d1, $d2)) . "\n";
echo json_encode($d1 + $d2) . "\n";
//result ["a","b","b","c","d"]
//result ["a","b","b","c","d"]
//result {"1":"a","2":"b","3":"b","4":"c"}

如果是数字键值的数组合并时,array_merge和array_merge_recursive结果都是对数组重新排序,而’+’则是保留了原本键值。