51

How can make it so array_merge() overwrites two keys with different values but same key index from two arrays?

for example, merging:

[0] => 'whatever'

with

[0] => 'whatever', [1] => 'a', [2] => 'b'

should produce

[0] => 'whatever', [1] => 'a', [2] => 'b'

Basically I want array_merge to bahave the same way it behaves if the arrays have string keys...

Alex
  • 66,732
  • 177
  • 439
  • 641
  • what you describe is array_merge yet your example is illustrating array addition. This is clear and as a result neither is the answer. If you are truly seeking an alternative to array_merge for numerical keys then the correct answer is [this one](https://stackoverflow.com/a/44026368/3596672) given by @HKandulla below. – Aurovrata Nov 26 '19 at 10:00

8 Answers8

96

Use the + operator.

Compare array_merge to + operator:

<?php

$a1 = array(0=>"whatever",);
$a2 = array(0=>"whatever",1=>"a",2=>"b");

print_r(array_merge($a1,$a2));
print_r($a1+$a2);
?>

Output:

Array
(
    [0] => whatever
    [1] => whatever
    [2] => a
    [3] => b
)
Array
(
    [0] => whatever
    [1] => a
    [2] => b
)

The + operator still works if your associative array has the numerical keys out-of-order:

<?php

$a1 = array(0=>"whatever",);
$a2 = array(1=>"a",0=>"whatever",2=>"b");

print_r(array_merge($a1,$a2));
print_r($a1+$a2);
?>

Output:

Array
(
    [0] => whatever
    [1] => a
    [2] => whatever
    [3] => b
)
Array
(
    [0] => whatever
    [1] => a
    [2] => b
)

Notice array_merge in this case creates a new key. Not desirable...

AJ.
  • 27,586
  • 18
  • 84
  • 94
  • 16
    you might want to use different values to demonstrate that "+" preserves left array values, while array_merge use right array values (for duplicate key case). – Anh Pham Feb 13 '13 at 23:30
  • 2
    Note: if you use `array $a1 + array $a2` - you will get correct data, where `$a1` will override $a2 values if key is the same (even indexed arrays), BUT: `json_encode()` of current sum will return object - not array!!! `array_values($a1+$a2)` will return shuffled result, and so on, and so on... , better to write one more loop and and merge manually... (i checked it before writing here, just a minute ago have some troubles in finding a problem why JS plugin don't want to work...) – LINKeRxUA Jun 01 '16 at 16:15
  • @LINKeRxUA I would rather run `ksort` on the array after the union than add a six-line function to handle that specific use case. – Brilliand Aug 24 '17 at 00:02
  • 3
    if PHP gods are reading this array_merge should simply have a flag that replicates the $arr1+$arr2 behaviour.. this is a bit silly – Robert Sinclair Sep 14 '18 at 22:31
  • 2
    this is not the answer to the question, [array_merge](https://www.php.net/manual/en/function.array-merge.php) will replace duplicate keys with later values except when keys are numeric. the proper answer is to use [array_replace](https://www.php.net/manual/en/function.array-replace.php) as given by @HKandulla [below](https://stackoverflow.com/a/44026368/3596672). – Aurovrata Nov 26 '19 at 09:57
28

array_replace does exactly this!

Aurovrata
  • 2,000
  • 27
  • 45
HKandulla
  • 1,101
  • 12
  • 17
7

Pretty easy to write manually:

function array_merge_custom($first, $second) {
    $result = array();
    foreach($first as $key => $value) {
        $result[$key] = $value;
    }
    foreach($second as $key => $value) {
        $result[$key] = $value;
    }

    return $result;
}

Update: This behaves differently than the union operator (return $first + $second;) because in this case the second array wins when both have elements with the same key.

However, if you switch the places of the arguments and place the array that you want to "win" in case of conflicts as the first operand, you can get the same behavior. So the function above behaves exactly like return $second + $first;.

Jon
  • 428,835
  • 81
  • 738
  • 806
3

In my project I use my own function

function array_merge_custom(){
    $array = [];
    $arguments  = func_num_args();
    foreach($arguments as $args)
        foreach($args as $key => $value)
            $array[$key] = $value;
    return $array;
}

Usage

$a = array_merge_custom($b, $c, $d, ... .. )
Manvel
  • 750
  • 7
  • 10
2

You should use $a2+$a1 to get same result with array_merge($a1,$a2);

$a1 = array(
    'k1' => 1,
    'k2' => 2,
    'k3' => 3,
);

$a2 = array(
    'k1' => 11,
    'k2' => 22,
    'k4' => 44,
);

Code:

print_r(array_merge($a1,$a2));

Output:

Array ( 
    [k1] => 11 
    [k2] => 22 
    [k3] => 3 
    [k4] => 44 
)

Code:

print_r($a1+$a2);

Output:

Array ( 
    [k1] => 1 
    [k2] => 2 
    [k3] => 3 
    [k4] => 44 
)

Code:

print_r($a2+$a1);

Output:

Array ( 
    [k1] => 11 
    [k2] => 22 
    [k4] => 44 
    [k3] => 3 
) 
0
the solution could be this:
function array_merge_custom($array1, $array2) {
    $mergeArray = [];
    $array1Keys = array_keys($array1);
    $array2Keys = array_keys($array2);
    $keys = array_merge($array1Keys, $array2Keys);

    foreach ($keys as $key) {
        $mergeArray[$key] = array_merge_recursive(isset($array1[$key]) ? $array1[$key] : [], isset($array2[$key]) ? $array2[$key] : []);
    }

    return $mergeArray;
}

$array1 = [
    '66_' => [
        'k1' => 1,
        'k2' => 1,
    ],
    '67_' => [
        'k1' => 1,
        'k2' => 1,
    ],
    '68_' => [
        'k1' => 1,
        'k2' => 1,
    ],
    68 => [
        'k1' => 1,
        'k2' => 1,
    ]
];
$array2 = [
    '66_' => [
        'a1' => 1,
        'a2' => 1,
    ],
    '68_' => [
        'b1' => 1,
        'b2' => 1,
    ],
    68 => [
        'b1' => 1,
        'b2' => 1,
    ]
];
echo '<pre>';
print_r(array_merge_custom($array1, $array2));
phvish
  • 149
  • 1
  • 8
0

You could use array_merge() and then use array_unique().

Scott C Wilson
  • 19,102
  • 10
  • 61
  • 83
-1
$arrA = [10, 11, 12];
$arrB = [12, 13];

$arrCommon = array_keys(array_flip($arrA) + array_flip($arrB));

print_r($arrCommon);
Array
(
    [0] => 10
    [1] => 11
    [2] => 12
    [3] => 13
)

Compare to WRONG use of "+"

$arrCommon = $arrA + $arrB;

print_r($arrCommon);
Array
(
    [0] => 10
    [1] => 11
    [2] => 12
)
Sergey Onishchenko
  • 6,943
  • 4
  • 44
  • 51