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

PHP将一个数组附加到另一个数组(不是数组推送或+;),php,arrays,function,Php,Arrays,Function,如何将一个数组附加到另一个数组而不比较它们的键 $a = array( 'a', 'b' ); $b = array( 'c', 'd' ); 最后应该是:Array([0]=>a[1]=>b[2]=>c[3]=>d) 如果我使用类似于[]或数组_push的内容,它将导致以下结果之一: Array( [0]=>a [1]=>b [2]=>Array( [0]=>c [1]=>d ) ) //or Array( [0]=>c [1]=>d ) 它应该是

如何将一个数组附加到另一个数组而不比较它们的键

$a = array( 'a', 'b' );
$b = array( 'c', 'd' );
最后应该是:
Array([0]=>a[1]=>b[2]=>c[3]=>d)
如果我使用类似于
[]
数组_push
的内容,它将导致以下结果之一:

Array( [0]=>a [1]=>b [2]=>Array( [0]=>c [1]=>d ) )
//or
Array( [0]=>c [1]=>d )
它应该是这样做的,但要以更优雅的方式:

foreach ( $b AS $var )
    $a[] = $var;
$a = array('a', 'b');
$b = array('c', 'd');
$merge = array_merge($a, $b); 
// $merge is now equals to array('a','b','c','d');
这个怎么样:

$appended = $a + $b;
为什么不使用

$appended = array_merge($a,$b); 
您为什么不想使用这一正确的内置方法。

是一种优雅的方式:

foreach ( $b AS $var )
    $a[] = $var;
$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));
?>

这是一篇很老的文章,但我想补充一些关于将一个数组附加到另一个数组的内容:

如果

  • 一个或两个数组都有关联键
  • 两个数组的键都不重要
您可以使用如下数组函数:

array_merge(array_values($array), array_values($appendArray));
array_merge不会合并数字键,因此它会附加$appendArray的所有值。虽然使用本机php函数而不是foreach循环,但在包含大量元素的数组上应该更快

新增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];
阵列(4){ [1]=> int(1) [4]=> int(2) [5]=> int(3) [6]=> int(4) }

$a=[1=>1,2=>2];
$b=[…$a,3=>3,1=>4];
阵列(3){ [0]=> int(1) [1]=> int(4) [3]=> int(3)
}

在PHP5.6+中执行此操作的另一种方法是使用
标记

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

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

// $a is now equals to array('a','b','c','d');
这也适用于任何可遍历的

$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
    是空数组或不可遍历(例如,不是数组),则会导致致命错误
  • 在PHP7.3中,如果
    $b
    不可遍历,则会发出警告

对于大数组,最好在不合并数组的情况下进行连接,以避免内存复制

$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);
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);
产生:

Test 1: 0.002717 
Test 2: 0.006922 
Test 3: 0.004744
原创:我相信从PHP7开始,方法3是一个更好的选择,因为它的方式是创建一个被迭代数组的副本

虽然方法3并不是严格地回答问题中的“非阵列推送”标准,但它是一条线,在所有方面都是最高性能的,我认为问题是在。。。语法是一种选择

更新日期:2020年3月25日: 我已经更新了有缺陷的测试,因为变量没有重置。有趣的是(或令人困惑的是),现在的结果显示测试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
$products=array();
//举个例子

对于PHP7之前的($brand_id=1;$brand_id),您可以使用:

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

array\u splice()
参照数组(第一个参数)和put数组(第四个参数)进行操作值代替从第二个参数开始的值列表和第三个参数的数量。当我们将第二个参数设置为源数组的结尾,将第三个参数设置为零时,我们将第四个参数值附加到第一个参数

foreach循环比array\u 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
//创建一个数组数组
$chars=[];
对于($i=0;$i<15000;$i++){
$chars[]=数组填充(0,10,'a');
}
//测试数组合并
$new=[];
$start=microtime(真);
foreach($chars作为$splitArray){
$new=array\u merge($new,$splitArray);
}
回波微时间(真)-$start;//=>14.61776秒
//测试foreach
$new=[];
$start=microtime(真);
foreach($chars作为$splitArray){
foreach($splitArray作为$value){
$new[]=$value;
}
}
回波微时间(真)-$start;//=>0.00900101秒
//==>快1600倍

因为PHP7.4你可以使用..操作符。这在其他语言中也被称为splat操作符,包括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"
}
Splat操作符应该比array\u merge具有更好的性能。这不仅是因为Splat操作符是一种语言结构,而array\u merge是一个函数,而且还因为编译时优化可以针对常量数组执行

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

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

正如我所说,它会比较键,结果如下:数组([0]=>a[1]=>b)你确定它会比较键吗?文档(我的重点)说:如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个值。但是,如果数组包含数字键,则后一个值不会覆盖原始值,而是将被追加。“。你确定你的键实际上不是
'0'=>'a'
…而不是
0=>'a'
?@Piskvor对于键来说,“0”和“0”没有区别。Gordon是对的。重点是数字键(与整数键相反)@Gordon:啊,你说得对-这就是我一次想到两件事所得到的。是
array+array
array\u merge的文档吗