Hem
Hem

Reputation: 105

Merge arrays containing shared associative keys without overwriting each other

I am working with multiple APIs returning data as flat arrays. All of these APIs are returning arrays with shared keys.

For example:

Returning data from API A,B and C:

$a = array(1 => "abc", 2 => "def");
$b = array(1 => "ghi", 2 => "jkl");
$c = array(1 => "mno", 2 => "pqr");

All of these arrays have repeated numeric keys. My requirement is a single array without losing values due to key collisions.

Required outcome:

array(
    "abc",
    "def",
    "ghi",
    "jkl",
    "mno",
    "pqr"
);

I tried array_merge() function but it overwrites the duplicated key and array_merge_recursive() function accumulate all repeated key into another array.

Upvotes: 2

Views: 727

Answers (4)

mickmackusa
mickmackusa

Reputation: 48100

Because your keys are all numeric, you can "splat-pack" the data by using variadic expressions inside of a new array. This is a one-liner that requires absolutely no function calls to generate the desired data structure.

Code: (Demo)

$a = [1 => "abc", 2 => "def"];
$b = [1 => "ghi", 2 => "jkl"];
$c = [1 => "mno", 2 => "pqr"];

var_export(
    [...$a, ...$b, ...$c]
);

Output:

array (
  0 => 'abc',
  1 => 'def',
  2 => 'ghi',
  3 => 'jkl',
  4 => 'mno',
  5 => 'pqr',
)

array_merge() provides the same results. (Demo)

var_export(array_merge($a, $b, $c));

And three language constructs will do the same thing. (Demo)

$result = [];
foreach ($a as $result[]);
foreach ($b as $result[]);
foreach ($c as $result[]);
var_export($result);

Alternatively, if you want the keys in the merged result array to start from 1, you can use variadic expressions inside of a single array_push() call. (Demo)

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

Output:

array (
  1 => 'abc',
  2 => 'def',
  3 => 'ghi',
  4 => 'jkl',
  5 => 'mno',
  6 => 'pqr',
)

You must not use array union operators, because they will destroy elements due to key collisions. (Demo)

var_export($a + $b + $c);

Bad Output:

array (
  1 => 'abc',
  2 => 'def',
)

Upvotes: 0

spenibus
spenibus

Reputation: 4409

This is a fairly short way to create an array containing all the values regardless of their keys:

$z = array_merge(
    array_values($a),
    array_values($b),
    array_values($c)
)

Upvotes: 1

denil
denil

Reputation: 690

You could use array_merge or array_merge_recursive.

For array_merge if you are using string keys the values will be overwritten meaning there will be only one value for that key on the output array.

For array_merge_recursive if you are using numeric keys the value will be overwritten meaning there will be only one value for that key in the output array

Upvotes: 1

Rohit Gaikwad
Rohit Gaikwad

Reputation: 815

Try this.......

$a=array(1=>"abc",2=>"def");
$b=array(1=>"ghi",2=>"jkl");
$c=array(1=>"mno",2=>"pqr");

$d = array();

foreach($a as $arr){
 array_push($d, $arr);
}

foreach($b as $arr){
 array_push($d, $arr);
}

foreach($c as $arr){
 array_push($d, $arr);
}
print_r($d);

Output is

Array ( [0] => abc [1] => def [2] => ghi [3] => jkl [4] => mno [5] => pqr )

I also tried your example with array merge & it gave me following o/p.

Array ( [0] => abc [1] => def [2] => ghi [3] => jkl [4] => mno [5] => pqr )

Upvotes: 2

Related Questions