skip to Main Content

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

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search