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

如何追加一个数组到另一个没有比较他们的键?

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

在结尾它应该是: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 )

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

foreach ( $b AS $var )
$a[] = $var;
550145 次浏览

为什么不使用

$appended = array_merge($a,$b);

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

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');

做这样的事情:

$merge = $a + $b;
// $merge now equals array('a','b')

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

<?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));
?>

输出:

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
)

参考源代码 .

这是一篇相当老的文章,但我想添加一些关于将一个数组附加到另一个数组的东西:

如果

  • 一个或两个数组都有关联键
  • 两个数组的键都不重要

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

array_merge(array_values($array), array_values($appendArray));

array_merge不合并数字键,所以它附加$appendArray的所有值。当使用原生php函数而不是foreach-loop时,它应该在包含大量元素的数组上更快。

< >强除了2019-12-13: 从PHP 7.4开始,就有可能以

的数组展开运算符方式追加或前置数组
    $a = [3, 4];
$b = [1, 2, ...$a];

和以前一样,这个新功能的键可能是一个问题:

    $a = ['a' => 3, 'b' => 4];
$b = ['c' => 1, 'a' => 2, ...$a];

"致命错误:未捕获错误:无法解包包含字符串键的数组"

    $a = [3 => 3, 4 => 4];
$b = [1 => 1, 4 => 2, ...$a];
< p >阵列(4){ [1] = > int (1) [4] = > int (2) [5] = > int (3) [6] = > int (4) } < / p >
    $a = [1 => 1, 2 => 2];
$b = [...$a, 3 => 3, 1 => 4];
< p >阵列(3){ [0] = > int (1) [1] = > int (4) [3] = > int (3) } < / p >

在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');

这也适用于任何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');

警告虽然:

  • 在7.3之前的PHP版本中,如果$b是空数组或不可遍历,例如不是数组,则会导致致命错误
  • 在PHP 7.3中,如果$b不可遍历,则会引发警告

对于大数组,最好不使用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

根据bstoney和Snark的回答,我对各种方法进行了一些测试:

// Test 1 (array_merge)
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
$array1 = array_merge($array1, $array2);
printf("Test 1: %.06f\n", microtime(true) - $start);


// Test2 (foreach)
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
foreach ($array2 as $v) {
$array1[] = $v;
}
printf("Test 2: %.06f\n", microtime(true) - $start);


// Test 3 (... token)
// PHP 5.6+ and produces error if $array2 is empty
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
array_push($array1, ...$array2);
printf("Test 3: %.06f\n", microtime(true) - $start);

生产:

Test 1: 0.002717
Test 2: 0.006922
Test 3: 0.004744

原文:我相信在PHP 7,方法3是一个明显更好的选择,由于Foreach循环现在开始的方式,这是使一个数组的副本被迭代。

虽然方法3并不是严格地回答问题中的'not array_push'的标准,但它是一行并且在各方面都是最高性能的,我认为这个问题在…语法是一个选项。

< p > 25/03/2020更新: 我已经更新了有缺陷的测试,因为变量没有重置。有趣的(或令人困惑的)结果现在显示测试1是最快的,而它是最慢的,从0.008392到0.002717!这只能归结于PHP更新,因为这不会受到测试缺陷的影响

所以,传奇继续,我将从现在开始使用array_merge !

如果您想合并空数组与现有的新值。您必须先初始化它。

$products = array();
//just example
for($brand_id=1;$brand_id<=3;$brand_id++){
array_merge($products,getByBrand($brand_id));
}
// it will create empty array
print_r($a);


//check if array of products is empty
for($brand_id=1;$brand_id<=3;$brand_id++){
if(empty($products)){
$products = getByBrand($brand_id);
}else{
array_merge($products,getByBrand($brand_id));
}
}
// it will create array of products

希望能有所帮助。

在PHP7之前,你可以使用:

array_splice($a, count($a), 0, $b);

array_splice()操作引用数组(第一个参数),并将数组(第四个参数)值放置在从第二个参数和第三个参数开始的值列表中。当我们将第2个参数设置为源数组的结束,第3个参数设置为零时,我们将第4个参数值附加到第1个参数

Foreach循环在向现有数组追加值方面比array_merge快,因此如果您想将一个数组添加到另一个数组的末尾,则选择该循环。

// Create an array of arrays
$chars = [];
for ($i = 0; $i < 15000; $i++) {
$chars[] = array_fill(0, 10, 'a');
}


// test array_merge
$new = [];
$start = microtime(TRUE);
foreach ($chars as $splitArray) {
$new = array_merge($new, $splitArray);
}
echo microtime(true) - $start; // => 14.61776 sec


// test foreach
$new = [];
$start = microtime(TRUE);
foreach ($chars as $splitArray) {
foreach ($splitArray as $value) {
$new[] = $value;
}
}
echo microtime(true) - $start; // => 0.00900101 sec
// ==> 1600 times faster

从PHP 7.4开始你可以使用... 操作符。这在其他语言中也被称为长条木板运营商,包括Ruby。

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

输出

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

长条木板运营商应该比array_merge有更好的性能。这不仅是因为splat操作符是一种语言结构,而array_merge是一个函数,而且还因为编译时优化可以用于常量数组。

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

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];