107

I have two arrays like this:

array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);

array( 
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);

I want to combine these two array such that it does not contains duplicate and as well as keep their original keys. For example output should be:

array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);

I have tried this but it is changing their original keys:

$output = array_unique( array_merge( $array1 , $array2 ) );

Any solution?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Awan
  • 18,096
  • 36
  • 89
  • 131

11 Answers11

194

Just use:

$output = array_merge($array1, $array2);

That should solve it. Because you use string keys if one key occurs more than one time (like '44' in your example) one key will overwrite preceding ones with the same name. Because in your case they both have the same value anyway it doesn't matter and it will also remove duplicates.

Update: I just realised, that PHP treats the numeric string-keys as numbers (integers) and so will behave like this, what means, that it renumbers the keys too...

A workaround is to recreate the keys.

$output = array_combine($output, $output);

Update 2: I always forget, that there is also an operator (in bold, because this is really what you are looking for! :D)

$output = $array1 + $array2;

All of this can be seen in: http://php.net/manual/en/function.array-merge.php

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • 5
    @KingCrunch - Even though the numbers are quoted, those are **not** string keys and so the index will **not** be preserved. Example: https://ideone.com/I2NFT – Brendan Bullen Jun 30 '11 at 13:29
  • 1
    Really... First I wanted to talk about "a bug", but then I noticed, that the manual only talks about "numeric keys", not "integer keys". Feels a little bit confusing. – KingCrunch Jun 30 '11 at 13:32
  • 4
    So `$array1 + $array2` is short and efficient solution instead of `array_merge() - array_combine()` combination – Awan Jun 30 '11 at 13:54
  • Obviously it is. I never realized the behaviour of `array_merge()` with numeric string-keys before and first I expected `+` and `array_merge()` behave nearly identical, but it seems, I've learned something :) – KingCrunch Jun 30 '11 at 14:01
  • 6
    WARNING! for non-assoc arrays or if arrays has common keys `$a + $b != array_merge($a, $b)` – jmarceli May 08 '18 at 15:21
  • For best performance do not use `array_merge()` but `$output = $array1 + $array2;`. See also https://gist.github.com/Ocramius/8399625 and https://stackoverflow.com/a/23348715/1066234 – Avatar May 22 '20 at 06:50
37

You should take to consideration that $array1 + $array2 != $array2 + $array1

$array1 = array(
'11' => 'x1',
'22' => 'x1' 
);  

$array2 = array(
'22' => 'x2',
'33' => 'x2' 
);

with $array1 + $array2

$array1 + $array2 = array(
'11' => 'x1',
'22' => 'x1',
'33' => 'x2'
);

and with $array2 + $array1

$array2 + $array1 = array(  
'11' => 'x1',  
'22' => 'x2',  
'33' => 'x2'  
);
inemanja
  • 1,312
  • 12
  • 15
31

This works:

$output = $array1 + $array2;
Mahdi Bashirpour
  • 17,147
  • 12
  • 117
  • 144
Michas
  • 8,534
  • 6
  • 38
  • 62
  • 19
    I would not recommend this because it's behavior is very unintuitive, e.g. `[1,2,3] + [4,5,6] == [1,2,3]` – jchook Oct 14 '16 at 23:56
  • @jchook What do You recommend then? – Michas Oct 15 '16 at 00:03
  • This is what I needed, thanks. Here's why: `http_build_query(array_merge($array1, $array2))` did not work for me, whereas `http_build_query($array1 + $array2)` did. – Barry Feb 06 '17 at 16:20
10

The new way of doing it with php7.4 is Spread operator [...]

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

Spread operator should have better performance than array_merge

A significant advantage of Spread operator is that it supports any traversable objects, while the array_merge function only supports arrays.

Shoaib Ahmed
  • 747
  • 12
  • 28
  • Of course, for this task, you would have tested this technique with the two numerically-keyed associative arrays and found that this approach DOES NOT provide the required behavior. 3v4l.org/KEQub This inappropriate/incorrect answer has been posted on the wrong page and has a score that will mislead researchers. – mickmackusa Mar 16 '23 at 21:21
  • I don't think the spread operator allows unpacking with string keys (at least on php 7.4). – mwm Jul 17 '23 at 11:39
4

To do this, you can loop through one and append to the other:

<?php

$test1 = array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);

$test2 = array( 
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);


function combineWithKeys($array1, $array2)
{
    foreach($array1 as $key=>$value) $array2[$key] = $value;
    asort($array2);
    return $array2;
} 

print_r(combineWithKeys($test1, $test2));

?>

UPDATE: KingCrunch came up with the best solution: print_r($array1+$array2);

Community
  • 1
  • 1
Brendan Bullen
  • 11,607
  • 1
  • 31
  • 40
1

Warning! $array1 + $array2 overwrites keys, so my solution (for multidimensional arrays) is to use array_unique()

array_unique(array_merge($a, $b), SORT_REGULAR);

Notice:

5.2.10+ Changed the default value of sort_flags back to SORT_STRING.

5.2.9 Default is SORT_REGULAR.

5.2.8- Default is SORT_STRING

It perfectly works. Hope it helps same.

Community
  • 1
  • 1
Norman Edance
  • 352
  • 4
  • 14
  • 1
    `array_merge()` doesn't preserve the keys though. The array created by that is 0 indexed. – HPierce Nov 21 '17 at 12:20
  • 1
    @HPierce well, in multidimensional array addition case, some information will be lost using `+`. Take a look at: [PHPFiddle](https://www.tehplayground.com/dHlrF78YWWh5jC8H) , $b[0] will be lost... – Norman Edance Nov 22 '17 at 06:00
1

If you are using PHP 7.4 or above, you can use the spread operator ... as the following examples from the PHP Docs:

$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; //[1, 2, 3]
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
$arr4 = array(...$arr1, ...$arr2, 111); //[1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]

function getArr() {
  return ['a', 'b'];
}
$arr6 = [...getArr(), 'c']; //['a', 'b', 'c']

$arr7 = [...new ArrayIterator(['a', 'b', 'c'])]; //['a', 'b', 'c']

function arrGen() {
    for($i = 11; $i < 15; $i++) {
        yield $i;
    }
}
$arr8 = [...arrGen()]; //[11, 12, 13, 14]

It works like in JavaScript ES6.

See more on https://wiki.php.net/rfc/spread_operator_for_array.

  • 1
    This is not applicable to the question. The OP has string keys for the array (That doesn"t work with the spread operator) and the OP wants to preserve the keys (the spread operator throws away the keys). Also OP doesn't want duplicates. – martti Mar 14 '20 at 19:54
  • Oh I see your points. That's true, and you're right. Can you provide some code to help us improve my answer for other people? I'd appreciate your time! Thank you very much for pointing out the drawbacks of my answer. – Student of Science Mar 15 '20 at 20:12
  • 1
    I don't think the spread operator is the way to go here. Instead use the given answer `$array1 + $array2` – martti Mar 16 '20 at 21:11
  • I wasn't aware of this! I mean, I didn't know that we can do `$ouput = $array1 + $array2`. Now I have learned something new! Thank you! – Student of Science Mar 17 '20 at 17:10
  • Any answer on this page that implements an approach with the spread operator is inappropriate/incorrect and should have been posted on a different page of Stack Overflow. This page very clearly asked about merging two arrays with numeric associative keys which must be preserved in the result. – mickmackusa Mar 16 '23 at 21:17
1

This works:

$a = array(1 => 1, 2 => 2, 3 => 3);
$b = array(4 => 4, 5 => 5, 6 => 6);
$c = $a + $b;
print_r($c);
elitalon
  • 9,191
  • 10
  • 50
  • 86
jeni
  • 442
  • 1
  • 4
  • 12
0

https://www.php.net/manual/en/function.array-merge.php

<?php
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>
0

This is slightly explored by @jchook in one of his comments, but it is worth highlighting that the + is not as consistant as one might expect. When you are dealing with keys which are the same, the results are not the same as array_merge.

$a1 = array(
    'hello',
    'world',
);

$a2 = array(
    'foo',
    'baz',
);

// Will NOT work - only outputs $a1
print'<pre>';print_r($a1 + $a2);print'</pre>';

$a1 = array(
    'a' => 'hello',
    'b' => 'world',
);

$a2 = array(
    'c' => 'foo',
    'd' => 'baz',
);

// Will work (however were a and b c and d - would equally fail
print'<pre>';print_r($a1 + $a2);print'</pre>';

$a1 = array(
    1=> 'hello',
    2=> 'world',
);

$a2 = array(
    3=>'foo',
    4=>'baz',
);

// Will work
print'<pre>';print_r($a1 + $a2);print'</pre>';
Antony
  • 3,875
  • 30
  • 32
  • [Merging two arrays with the "+" (array union operator) How does it work?](https://stackoverflow.com/q/2140090/2943403) – mickmackusa Jan 25 '23 at 02:26
-1

We can combine two arrays in PHP using the spread operator (...).

In this example, $array1 contains the values 1 through 10, and $array2 contains the values 11 through 20. The spread operator is used to concatenate(combine) the two arrays into a single array called $data.

// Define the first array
$array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Define the second array
$array2 = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

// Use the spread operator to concatenate the two arrays into a single array
$data = [...$array1, ...$array2];

// Print the contents of the combined array
print_r($data);

  • 1
    This answer is a duplicate of several others, but worse because it doesn't contain an explanation. – cyberbrain Feb 16 '23 at 19:26
  • Any answer on this page that implements an approach with the spread operator is inappropriate/incorrect and should have been posted on a different page of Stack Overflow. This page very clearly asked about merging two arrays with numeric associative keys which must be preserved in the result. – mickmackusa Mar 16 '23 at 21:19