398

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]=>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;
5
  • 27
    array_merge ($a, $b) should do exactly what you want, at least with PHP 5+. Commented Nov 24, 2010 at 16:15
  • 1
    (related) + Operator for Array in PHP Commented Nov 24, 2010 at 16:17
  • 6
    none of the outputs you posted come from array_merge(); the output of array_merge(); should be exaclty what you need: print_r(array_merge($a,$b)); // outputs => Array ( [0] => a [1] => b [2] => c [3] => d ) Commented Nov 24, 2010 at 16:18
  • 4
    I totally disagree with the term "append". Append really means that items of one array become elements of another (destination) array which might already has some elements, therefore changing the destination array. Merge allocates a new array and COPIES elements of both arrays, while append actually means reusing the destination array elements without extra memory allocation. Commented Jul 23, 2014 at 16:00
  • All methods are described on the page [PHP-docs] in "User Contributed Notes" [1]: php.net/manual/ru/function.array-push.php Commented Aug 15, 2021 at 21:08

9 Answers 9

582

array_merge is the elegant way:

$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 $a has the same keys as $b, it won't do anything.

Sign up to request clarification or add additional context in comments.

1 Comment

Just be careful if your keys are not a numbers but strings, From doc: If the input arrays have the same string keys, then the later value for that key will overwrite the previous one
176

Another way to do this in PHP 5.6+ would be to use the ... token

$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

$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 warning though:

  • in PHP versions before 7.3 this will cause a fatal error if $b is an empty array or not traversable e.g. not an array
  • in PHP 7.3 a warning will be raised if $b is not traversable

6 Comments

Which term is used for such syntax? (E.g. in JS it is called spread operator ) Or can you provide link to docs?
@basil you will find ... commonly referred to as the splat operator in php.
The most useful answer when looking for a simple way to append an array to itself without overriding any previous elements.
array_push accepts a single argument since php 7.3, which prevents errors with empty arrays.
A little note: This doesn't work with associative arrays. (Fatal Error: Cannot unpack array with string keys)
|
42

Why not use

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

Why don't you want to use this, the correct, built-in method.

4 Comments

Where does OP say he "doesn't want to use" array_merge()...?
@KittenCodings - Read the "edit history" of the question... the original question was entitled PHP append one array to another (not array_merge or array_push)... subsequently modified to PHP append one array to another (not array_merge or +) before changing to its current title
@MarkBaker Wow! I didn't know SO has an edit history! Sorry about that, and thanks, this changes a lot and somewhat prevents moderators from putting words into peoples mouths, I previously felt like some questions were defaced and their comments invalidated by content removed/edited, though I imagine most people probably don't read the edit history, I sure as heck will from now on
array_merge can be a performance hit in certain cases.
33

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.

Addition 2019-12-13: Since PHP 7.4, there is the possibility to append or prepend arrays the Array Spread Operator way:

    $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) }

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

array(3) { [0]=> int(1) [1]=> int(4) [3]=> int(3) }

2 Comments

This should also have the advantage of leaving the input arrays untouched.
Yes it is more safe just in case to extract the array_values so that you don't merge into the same keys.
20
<?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
)

1 Comment

you are quite thorough with your answer; of import for me is the example noting that when keys are the same (for associative arrays), array_merge might behave contrary to expectation for those who simply takes it at its name.
15

Following on from answer's by bstoney and Snark I did some tests on the various methods:

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

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.

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.

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.

So, the saga continues, I will start using array_merge from now on!

3 Comments

You call array_merge() only once. But what if you have a large array being appended many times with smaller ones ?
I would guess (I haven't tested) that concatenation would be better in this case, as it would avoid the memory copy. However, if anything I've learnt anything from PHP performance optimisation / measurement, is that it's very difficult to pin down, then changes with an update. I go with what's the nicest to look at these days :)
This answer very nicely demonstrates why premature optimization is the root of all evil. Caring of such minor things is at best a waste of time.
14

For big array, is better to concatenate without array_merge, for avoid a memory copy.

$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

1 Comment

echo sprintf() should never exist in anyone's code. Just write printf() without the echo.
12

Since PHP 7.4 you can use the ... operator. This is also known as the splat operator in other languages, including 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"
}

Moreover, we can use the splat operator syntax everywhere in the array, as normal elements can be added before or after the splat operator.

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

1 Comment

Splat was recommended back in php5.6 stackoverflow.com/a/37065301/2943403
4

Before PHP7 you can use:

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.