PHP将一个数组附加到另​​一个数组(不是array_push或+)

Dan*_*l K 251 php arrays function

如何在不比较键的情况下将一个数组附加到另​​一个数组?

$a = array( 'a', 'b' );
$b = array( 'c', 'd' );
Run Code Online (Sandbox Code Playgroud)

在结束它应该是:Array( [0]=>a [1]=>b [2]=>c [3]=>d ) 如果我使用类似[]或者array_push,它会导致这些结果之一:

Array( [0]=>a [1]=>b [2]=>Array( [0]=>c [1]=>d ) )
//or
Array( [0]=>c [1]=>d )
Run Code Online (Sandbox Code Playgroud)

它应该是一些东西,这样做,但以更优雅的方式:

foreach ( $b AS $var )
    $a[] = $var;
Run Code Online (Sandbox Code Playgroud)

net*_*der 394

array_merge 是优雅的方式:

$a = array('a', 'b');
$b = array('c', 'd');
$merge = array_merge($a, $b); 
// $merge is now equals to array('a','b','c','d');
Run Code Online (Sandbox Code Playgroud)

做类似的事情:

$merge = $a + $b;
// $merge now equals array('a','b')
Run Code Online (Sandbox Code Playgroud)

不起作用,因为+运营商实际上并没有合并它们.如果它们$a具有相同的键$b,它将不会执行任何操作.

  • 如果你的键不是数字而是字符串,请小心.来自doc:如果输入数组具有相同的字符串键,那么该键的后一个值将覆盖前一个键 (11认同)

bst*_*ney 63

在PHP 5.6+中执行此操作的另一种方法是使用...令牌

$a = array('a', 'b');
$b = array('c', 'd');

array_push($a, ...$b);

// $a is now equals to array('a','b','c','d');
Run Code Online (Sandbox Code Playgroud)

这也适用于任何 Traversable

$a = array('a', 'b');
$b = new ArrayIterator(array('c', 'd'));

array_push($a, ...$b);

// $a is now equals to array('a','b','c','d');
Run Code Online (Sandbox Code Playgroud)

但是警告,如果数组$b为空,这将导致致命错误

  • 当寻找一种简单的方法将数组附加到自身而不覆盖任何先前的元素时,最有用的答案。 (3认同)
  • @basil,您会发现`...`在php中通常称为`splat运算符`。 (2认同)
  • 请注意:这不适用于关联数组。(致命错误:无法使用字符串键解压数组) (2认同)

Mar*_*ker 32

为什么不用

$appended = array_merge($a,$b); 
Run Code Online (Sandbox Code Playgroud)

你为什么不想使用这个正确的内置方法.

  • @KittenCodings - 阅读问题的"编辑历史"......最初的问题是`PHP将一个数组附加到另​​一个(不是array_merge或array_push)`...随后修改为`PHP将一个数组附加到另​​一个数组(不是array_merge)或+)`在更改为当前标题之前 (3认同)
  • @MarkBaker哇!我不知道有编辑记录!对此感到抱歉,谢谢,这发生了很大的变化,并在一定程度上阻止了版主发表言论,我以前觉得有些问题被污损了,他们的评论被内容删除/编辑了,尽管我想大多数人可能不会阅读编辑历史,我确信从现在开始 (2认同)

Sen*_*ion 17

这是一个非常古老的帖子,但我想添加一些关于将一个数组附加到另​​一个数组的内容:

如果

  • 一个或两个数组都有关联键
  • 两个数组的键无关紧要

你可以使用这样的数组函数:

array_merge(array_values($array), array_values($appendArray));
Run Code Online (Sandbox Code Playgroud)

array_merge不合并数字键,因此它附加$ appendArray的所有值.使用本机php函数而不是foreach循环时,在具有大量元素的数组上应该更快.


小智 15

<?php
// Example 1 [Merging associative arrays. When two or more arrays have same key
// then the last array key value overrides the others one]

$array1 = array("a" => "JAVA", "b" => "ASP");
$array2 = array("c" => "C", "b" => "PHP");
echo " <br> Example 1 Output: <br>";
print_r(array_merge($array1,$array2));

// Example 2 [When you want to merge arrays having integer keys and
//want to reset integer keys to start from 0 then use array_merge() function]

$array3 =array(5 => "CSS",6 => "CSS3");
$array4 =array(8 => "JAVASCRIPT",9 => "HTML");
echo " <br> Example 2 Output: <br>";
print_r(array_merge($array3,$array4));

// Example 3 [When you want to merge arrays having integer keys and
// want to retain integer keys as it is then use PLUS (+) operator to merge arrays]

$array5 =array(5 => "CSS",6 => "CSS3");
$array6 =array(8 => "JAVASCRIPT",9 => "HTML");
echo " <br> Example 3 Output: <br>";
print_r($array5+$array6);

// Example 4 [When single array pass to array_merge having integer keys
// then the array return by array_merge have integer keys starting from 0]

$array7 =array(3 => "CSS",4 => "CSS3");
echo " <br> Example 4 Output: <br>";
print_r(array_merge($array7));
?>
Run Code Online (Sandbox Code Playgroud)

输出:

Example 1 Output:
Array
(
[a] => JAVA
[b] => PHP
[c] => C
)

Example 2 Output:
Array
(
[0] => CSS
[1] => CSS3
[2] => JAVASCRIPT
[3] => HTML
)

Example 3 Output:
Array
(
[5] => CSS
[6] => CSS3
[8] => JAVASCRIPT
[9] => HTML
)

Example 4 Output:
Array
(
[0] => CSS
[1] => CSS3
)
Run Code Online (Sandbox Code Playgroud)

参考源代码


小智 12

对于大数组,最好不要使用array_merge连接,以避免内存复制.

$array1 = array_fill(0,50000,'aa');
$array2 = array_fill(0,100,'bb');

// Test 1 (array_merge)
$start = microtime(true);
$r1 = array_merge($array1, $array2);
echo sprintf("Test 1: %.06f\n", microtime(true) - $start);

// Test2 (avoid copy)
$start = microtime(true);
foreach ($array2 as $v) {
    $array1[] = $v;
}
echo sprintf("Test 2: %.06f\n", microtime(true) - $start);


// Test 1: 0.004963
// Test 2: 0.000038
Run Code Online (Sandbox Code Playgroud)


Jam*_*son 8

继bstoney和Snark的回答后,我对各种方法做了一些测试:

$array1 = array_fill(0,50000,'aa');
$array2 = array_fill(0,50000,'bb');

// Test 1 (array_merge)
$start = microtime(true);
$array1 = array_merge($array1, $array2);
echo sprintf("Test 1: %.06f\n", microtime(true) - $start);

// Test2 (foreach)
$start = microtime(true);
foreach ($array2 as $v) {
    $array1[] = $v;
}
echo sprintf("Test 2: %.06f\n", microtime(true) - $start);

// Test 3 (... token)
// PHP 5.6+ and produces error if $array2 is empty
$start = microtime(true);
array_push($array1, ...$array2);
echo sprintf("Test 3: %.06f\n", microtime(true) - $start);
Run Code Online (Sandbox Code Playgroud)

哪个产生:

Test 1: 0.008392 
Test 2: 0.004626 
Test 3: 0.003574
Run Code Online (Sandbox Code Playgroud)

我相信从PHP 7开始,方法3是一个明显更好的选择,因为foreach循环现在的行为方式,即使迭代的数组副本.

虽然方法3并不严格地回答问题中"not array_push"的标准,但它在所有方面都是一行和最高性能,我认为问题是在......语法之前提出的.

  • 您不会在每次测试之前重置 array1,因此每个测试比前一个测试多 50,000 个项目。 (2认同)

dta*_*tar 7

自 PHP 7.4 起,您可以使用... 运算符。这在其他语言中也称为splat 运算符,包括 Ruby。

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);
Run Code Online (Sandbox Code Playgroud)

输出

array(5) {
    [0]=>
    string(6) "banana"
    [1]=>
    string(6) "orange"
    [2]=>
    string(5) "apple"
    [3]=>
    string(4) "pear"
    [4]=>
    string(10) "watermelon"
}
Run Code Online (Sandbox Code Playgroud)

Splat 运算符应该比array_merge具有更好的性能。这不仅是因为 splat 运算符是一种语言结构,而 array_merge 是一个函数,而且还因为编译时优化可以对常量数组进行优化。

此外,我们可以在数组中的任何地方使用 splat 运算符语法,因为可以在 splat 运算符之前或之后添加普通元素。

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];
Run Code Online (Sandbox Code Playgroud)