PHP Merge two arrays by keeping higher value if keys are the same

66 views Asked by At

I want to merge two arrays by keeping higher value if keys are the same in PHP. Also would like to keep array keys.

I am not looking for a solution to manually go through arrays and compare values, I was thinking about some combination with array_replase and callback call if possible.

Example:

$array1 = [
    4 => [
        'name' => 'John',
        'value' => '5',
    ],
    5 => [
        'name' => 'Michael',
        'value' => '4',
    ],
    6 => [
        'name' => 'Steve',
        'value' => '7',
    ],
]

$array2 = [
    5 => [
        'name' => 'Peter',
        'value' => '6',
    ],
    6 => [
        'name' => 'Glen',
        'value' => '3',
    ],
]

Expected result:

$result = [
    4 => [
        'name' => 'John',
        'value' => '5',
    ],
    5 => [
        'name' => 'Peter',
        'value' => '6',
    ],
    6 => [
        'name' => 'Steve',
        'value' => '7',
    ],
]
2

There are 2 answers

0
KIKO Software On

Just to show you that this can also be solved with a simple foreach loop:

// first get the elements that are present in both arrays
$intersect = array_intersect_key($array1, $array2);
// the intersect may need the element of array 2 instead of array 1
foreach ($intersect as $key => $data) {
    if ($data['value'] < $array2[$key]['value']) {
        $intersect[$key] = $array2[$key];
    }
}
// add the elements that are unique to each input array
$result = $intersect +
         array_diff_key($array1, $intersect) +
         array_diff_key($array2, $intersect);
// sort result
ksort($result);

You could replace the foreach with a array_walk:

array_walk($intersect, function ($data, $key, $array2) {
    if ($data['value'] < $array2[$key]['value']) {
        $data = $array2[$key];
    }
}, $array2);

which functionally does exactly the same, but is it as easy to read? I don't think so.

0
GrigorAtaryan On

Lets Combine Both Arrays: First, combine both arrays => If they have the same key, array_replace will use the value from the second array.

Apply a Callback Function: Use array_map with a custom callback function.This function will compare the values of the same keys in both arrays and keep the one with the higher value.

$array1 = [
    4 => ['name' => 'John', 'value' => '5'],
    5 => ['name' => 'Michael', 'value' => '4'],
    6 => ['name' => 'Steve', 'value' => '7'],
];

$array2 = [
    5 => ['name' => 'Peter', 'value' => '6'],
    6 => ['name' => 'Glen', 'value' => '3'],
];

// Combine arrays

$combined = array_replace($array1, $array2);

// Apply callback function to keep higher values

$result = array_map(function ($key) use ($array1, $array2) {
    if (isset($array1[$key]) && isset($array2[$key])) {
        return $array1[$key]['value'] >= $array2[$key]['value'] ? $array1[$key] : $array2[$key];
    }
    return isset($array1[$key]) ? $array1[$key] : $array2[$key];
}, array_keys($combined));

print_r($result);

Hope this should resolve.