PHP 将一个数组附加到另一个数组(不是 array_push 或 +)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4268871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP append one array to another (not array_push or +)
提问by Danil K
How to append one array to another without comparing their keys?
如何在不比较它们的键的情况下将一个数组附加到另一个数组?
$a = array( 'a', 'b' );
$b = array( 'c', 'd' );
At the end it should be: Array( [0]=>a [1]=>b [2]=>c [3]=>d )If I use something like []or array_push, it will cause one of these results:
最后应该是:Array( [0]=>a [1]=>b [2]=>c [3]=>d )如果我使用类似[]or 的东西array_push,它会导致以下结果之一:
Array( [0]=>a [1]=>b [2]=>Array( [0]=>c [1]=>d ) )
//or
Array( [0]=>c [1]=>d )
It just should be something, doing this, but in a more elegant way:
它应该是一些东西,这样做,但以一种更优雅的方式:
foreach ( $b AS $var )
$a[] = $var;
回答by netcoder
array_mergeis the elegant way:
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');
Doing something like:
做类似的事情:
$merge = $a + $b;
// $merge now equals array('a','b')
Will not work, because the +operator does not actually merge them. If they $ahas the same keys as $b, it won't do anything.
不会工作,因为+运营商实际上并没有合并它们。如果它们与$a具有相同的键$b,则不会执行任何操作。
回答by bstoney
Another way to do this in PHP 5.6+ would be to use the ...token
在 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');
This will also work with any Traversable
这也适用于任何 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');
A warningthough:
一个警告:
- in PHP versions before 7.3 this will cause a fatal error if
$bis an empty array or not traversable e.g. not an array - in PHP 7.3 a warning will be raised if
$bis not traversable
- 在 7.3 之前的 PHP 版本中,如果
$b是空数组或不可遍历(例如不是数组),这将导致致命错误 - 在 PHP 7.3 中,如果
$b不可遍历将引发警告
回答by Mark Baker
Why not use
为什么不使用
$appended = array_merge($a,$b);
Why don't you want to use this, the correct, built-in method.
你为什么不想使用这个,正确的内置方法。
回答by SenseException
It's a pretty old post, but I want to add something about appending one array to another:
这是一篇很老的帖子,但我想添加一些关于将一个数组附加到另一个数组的内容:
If
如果
- one or both arrays have associative keys
- the keys of both arrays don't matter
- 一个或两个数组具有关联键
- 两个数组的键无关紧要
you can use array functions like this:
您可以使用这样的数组函数:
array_merge(array_values($array), array_values($appendArray));
array_merge doesn't merge numeric keys so it appends all values of $appendArray. While using native php functions instead of a foreach-loop, it should be faster on arrays with a lot of elements.
array_merge 不合并数字键,因此它附加 $appendArray 的所有值。虽然使用原生 php 函数而不是 foreach 循环,但在具有大量元素的数组上应该更快。
Addition 2019-12-13:Since PHP 7.4, there is the possibility to append or prepend arrays the Array Spread Operator way:
添加 2019-12-13:自 PHP 7.4 起,可以使用 Array Spread Operator 方式附加或添加数组:
$a = [3, 4];
$b = [1, 2, ...$a];
As before, keys can be an issue with this new feature:
和以前一样,密钥可能是这个新功能的一个问题:
$a = ['a' => 3, 'b' => 4];
$b = ['c' => 1, 'a' => 2, ...$a];
"Fatal error: Uncaught Error: Cannot unpack array with string keys"
“致命错误:未捕获错误:无法使用字符串键解压数组”
$a = [3 => 3, 4 => 4];
$b = [1 => 1, 4 => 2, ...$a];
array(4) { [1]=> int(1) [4]=> int(2) [5]=> int(3) [6]=> int(4) }
数组(4) { [1]=> int(1) [4]=> int(2) [5]=> int(3) [6]=> int(4) }
$a = [1 => 1, 2 => 2];
$b = [...$a, 3 => 3, 1 => 4];
array(3) { [0]=> int(1) [1]=> int(4) [3]=> int(3) }
数组(3) { [0]=> int(1) [1]=> int(4) [3]=> int(3) }
回答by Hassan Amir Khan
<?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));
?>
Output:
输出:
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
)
回答by Snark
For big array, is better to concatenate without array_merge, for avoid a memory copy.
对于大数组,最好在没有 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
回答by Jamie Robinson
Following on from answer's by bstoney and Snark I did some tests on the various methods:
继 bstoney 和 Snark 的回答之后,我对各种方法进行了一些测试:
// Test 1 (array_merge)
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
$array1 = array_merge($array1, $array2);
echo sprintf("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;
}
echo sprintf("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);
echo sprintf("Test 3: %.06f\n", microtime(true) - $start);
Which produces:
其中产生:
Test 1: 0.002717
Test 2: 0.006922
Test 3: 0.004744
ORIGINAL: I believe as of PHP 7, method 3 is a significantly better alternative due to the way foreach loops now act, which is to make a copy of the array being iterated over.
原文:我相信从 PHP 7 开始,由于foreach 循环现在的行为方式,方法 3 是一个明显更好的替代方案,即制作正在迭代的数组的副本。
Whilst method 3 isn't strictly an answer to the criteria of 'not array_push' in the question, it is one line and the most high performance in all respects, I think the question was asked before the ... syntax was an option.
虽然方法 3 严格来说并不是问题中“not array_push”标准的答案,但它是一行并且在所有方面都具有最高的性能,我认为这个问题是在 ... 语法是一个选项之前提出的。
UPDATE 25/03/2020: I've updated the test which was flawed as the variables weren't reset. Interestingly (or confusingly) the results now show as test 1 being the fastest, where it was the slowest, having gone from 0.008392 to 0.002717! This can only be down to PHP updates, as this wouldn't have been affected by the testing flaw.
2020 年 3 月 25 日更新:我更新了有缺陷的测试,因为变量没有重置。有趣的是(或令人困惑)结果现在显示测试 1 是最快的,它是最慢的,从 0.008392 变为 0.002717!这只能归结为 PHP 更新,因为这不会受到测试缺陷的影响。
So, the saga continues, I will start using array_merge from now on!
所以,传奇还在继续,我将从现在开始使用 array_merge!
回答by dtar
Since PHP 7.4you can use the ... operator. This is also known as the splat operatorin other languages, including Ruby.
自 PHP 7.4 起,您可以使用... 运算符。这在其他语言中也称为splat 运算符,包括 Ruby。
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);
Output
输出
array(5) {
[0]=>
string(6) "banana"
[1]=>
string(6) "orange"
[2]=>
string(5) "apple"
[3]=>
string(4) "pear"
[4]=>
string(10) "watermelon"
}
Splat operatorshould have better performance than array_merge. That's not only because the splat operator is a language structure while array_merge is a function, but also because compile time optimization can be performant for constant arrays.
Splat 运算符应该比array_merge具有更好的性能。这不仅是因为 splat 运算符是一种语言结构,而 array_merge 是一个函数,而且还因为编译时优化可以对常量数组执行。
Moreover, we can use the splat operator syntax everywhere in the array, as normal elements can be added before or after the splat operator.
此外,我们可以在数组中的任何地方使用 splat 运算符语法,因为可以在 splat 运算符之前或之后添加普通元素。
$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];
回答by tutankhamun
Before PHP7 you can use:
在 PHP7 之前,您可以使用:
array_splice($a, count($a), 0, $b);
array_splice()operates with reference to array (1st argument) and puts array (4th argument) values in place of list of values started from 2nd argument and number of 3rd argument. When we set 2nd argument as end of source array and 3rd as zero we append 4th argument values to 1st argument
array_splice()参考数组(第一个参数)进行操作,并用数组(第四个参数)值代替从第二个参数和第三个参数的数量开始的值列表。当我们将第二个参数设置为源数组的结尾并将第三个参数设置为零时,我们将第四个参数值附加到第一个参数
回答by user3226852
foreach loop is faster than array_merge to append values to an existing array, so choose the loop instead if you want to add an array to the end of another.
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

