Search code examples
phparraysfilterarray-mergearray-key

How to merge two arrays by taking over only values from the second array that has the same keys as the first one?


I'd like to merge two arrays with each other:

$filtered = array(1 => 'a', 3 => 'c');
$changed = array(2 => 'b*', 3 => 'c*');

Whereas the merge should include all elements of $filtered and all those elements of $changed that have a corresponding key in $filtered:

$merged = array(1 => 'a', 3 => 'c*');

array_merge($filtered, $changed) would add the additional keys of $changed into $filtered as well. So it does not really fit.

I know that I can use $keys = array_intersect_key($filtered, $changed) to get the keys that exist in both arrays which is already half of the work.

However I'm wondering if there is any (native) function that can reduce the $changed array into an array with the $keys specified by array_intersect_key? I know I can use array_filter with a callback function and check against $keys therein, but there is probably some other purely native function to extract only those elements from an array of which the keys can be specified?

I'm asking because the native functions are often much faster than array_filter with a callback.


Solution

  • This should do it, if I'm understanding your logic correctly:

    array_intersect_key($changed, $filtered) + $filtered
    

    Implementation:

    $filtered = array(1 => 'a', 3 => 'c');
    $changed = array(2 => 'b*', 3 => 'c*');
    $expected = array(1 => 'a', 3 => 'c*');    
    $actual = array_key_merge_deceze($filtered, $changed);
    
    var_dump($expected, $actual);
    
    function array_key_merge_deceze($filtered, $changed) {
        $merged = array_intersect_key($changed, $filtered) + $filtered;
        ksort($merged);
        return $merged;
    }
    

    Output:

    Expected:
    array(2) {
      [1]=>
      string(1) "a"
      [3]=>
      string(2) "c*"
    }
    
    Actual:
    array(2) {
      [1]=>
      string(1) "a"
      [3]=>
      string(2) "c*"
    }