Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP array_intersect_key but keep values from array2

I have 2 arrays:

$array1 = ["b" => "no", "c" => "no", "d" => ["y" => "no"]];
$array2 = ["a" => "yes", "b" => "yes", "c" => "yes", "d" => ["x" => "yes", "y" => "yes", "z" => "yes"]];

I want to return the members of $array2 whose keys are also present in $array1.

Desired output:

$array3 = ["b" => "yes", "c" => "yes", "d" => ["y" => "yes"]];

Basically I need the same functionality as array_intersect_key but I want to keep the values from $array2 instead of $array1.

Does such a function exist? Also needs to recurse into child arrays. Thanks!

*Edit* As Andri suggested in his comment, I attempted to flip the arguments around array_intersect_key($array2, $array1) but in that case what I actually get is:

$array3 = ["b" => "yes", "c" => "yes", "d" => ["x" => "yes", "y" => "yes", "z" => "yes"]];

ie all the children of "d" just because "d" is mentioned in $array1.

like image 271
bbeckford Avatar asked Sep 25 '26 16:09

bbeckford


2 Answers

There isn't as far as I'm aware a built in function, a method using recursion to process all layers should be easy enough...

$array1 = ["b" => "no", "c" => "no", "d" => ["y" => "no"]];
$array2 = ["a" => "yes", "b" => "yes", "c" => "yes", "d" => ["x" => "yes", "y" => "yes", "z" => "yes"]];

function intersect_key_2 ( array $a1, array $a2 )   {
    foreach ( $a1 as $key1 => $value1)  {
        // If there is a matching element
        if ( isset($a2[$key1]) )    {
            // Update - if an array, use recursive call else just replace
            $a1[$key1] = ( is_array($value1) ) ? intersect_key_2 ( $value1, $a2[$key1])
                    : $a2[$key1];
        }
    }

    return $a1;
}

print_r(intersect_key_2($array1, $array2));

gives

Array
(
    [b] => yes
    [c] => yes
    [d] => Array
        (
            [y] => yes
        )

)
like image 104
Nigel Ren Avatar answered Sep 27 '26 04:09

Nigel Ren


Ended up writing my own:

function array_intersect_key_values_2($array1, $array2) : array {

    $intersection = [];

    foreach ($array1 as $key => $value) {
        if(isset($array2[$key]))
        {
            if(is_array($array1[$key]) && is_array($array2[$key]))
            {
                $intersection[$key] = array_intersect_key_values_2($array1[$key], $array2[$key]);
            }
            else
            {
                $intersection[$key] = $array2[$key];
            }
        }
    }

    return($intersection);
}
like image 21
bbeckford Avatar answered Sep 27 '26 04:09

bbeckford