Let's say I have following arrays:
Array
(
[0] => Array
(
[id] => 5
[name] => Education
)
[1] => Array
(
[id] => 4
[name] => Computers
)
[3] => Array
(
[id] => 7
[name] => Science
[4] => Array
(
[id] => 1
[name] => Sports
)
)
And the second one:
Array
(
[0] => Array
(
[id] => 1
[title] => Sport
)
[1] => Array
(
[id] => 7
[title] => Sci
)
[3] => Array
(
[id] => 4
[title] => Comp
[4] => Array
(
[id] => 5
[title] => Edu
)
)
And desired output is:
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Edu
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Comp
)
[3] => Array
(
[id] => 7
[name] => Science
[title] => Sci
[4] => Array
(
[id] => 1
[name] => Sports
[title] => Sport
)
)
I have managed to merge these arrays with simply:
foreach($first as $key => $value){
$result[$key] = array_merge($first[$key], $second[$key]);
}
But the output is not combined correctly:
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Sport
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Sci
)
[3] => Array
(
[id] => 7
[name] => Science
[title] => Comp
[4] => Array
(
[id] => 1
[name] => Sports
[title] => Edu
)
)
The problem is I would like to merge these arrays on the same id
.
Desired output sorting should be same as in the first array.
How can I achieve this? Any help is much appreciated.
This can be easily done using the 3-parameter form of array_column
to re-index your second
array by the id
value and then looping over the first
array, merging the contents of the matching second
value (where it exists):
$second = array_column($second, null, 'id');
foreach ($first as &$subject) {
$subject = array_merge($subject, $second[$subject['id']] ?? []);
}
Output:
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Edu
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Comp
)
[3] => Array
(
[id] => 7
[name] => Science
[title] => Sci
)
[4] => Array
(
[id] => 1
[name] => Sports
[title] => Sport
)
)
Demo on 3v4l.org
This has the advantage over Will B.'s answer of not re-indexing the first
array. It's also slightly faster (my tests show ~10%) due to only having one call to array_column
and none to array_values
.
Update
This code can actually be sped up even more by using the array union operator (+
) (thanks @mickmackusa):
$second = array_column($second, null, 'id');
foreach ($first as &$subject) {
$subject += $second[$subject['id']] ?? [];
}
The output of this code is the same as above, but it runs about 10% faster again.
Demo on 3v4l.org
You can just do a nested loop and check if the id
values match, then add title
to $first
(or name
to $second
)
foreach($first as $key => $value){
foreach($second as $value2){
if($value['id'] === $value2['id']){
$first[$key]['title'] = $value2['title'];
}
}
}
To provide an alternative approach available in PHP 5.5+
.
Since the ordering of the two arrays is not identical, first use array_column to index the arrays by the id
.
This will allow you to use array_replace_recusrive on the id
indexed arrays.
array_replace_recursive
will merge the values in the arrays matching the index association of both array sets.
Optionally use array_values
to reindex the array, removing the id
index association.
$first = array_column($first, null, 'id');
$second = array_column($second, null, 'id');
$result = array_values(array_replace_recursive($first, $second));
Result
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Edu
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Comp
)
[2] => Array
(
[id] => 7
[name] => Science
[title] => Sci
)
[3] => Array
(
[id] => 1
[name] => Sports
[title] => Sport
)
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With