2

I would like to apply array_diff_key() recursively on 2 multidimensional arrays and to find the difference between them.

It is important that the function will be "bidirectional" so foo($a, $b) and foo($b, $a) will produce the same result.

What I have tried? To be honest, I have tried too many things (including examples from http://php.net/manual/en/function.array-diff-key.php) and got lost.

function superMatch($a1, $a2) {

    foreach($a1 as $k => $v) {
        $r[$k] = is_array($v) ? superMatch($a1[$k], $a2[$k]) : array_diff_key($a1, $a2);
    }

    return $r;
}

Input:

$a = array('a' => 'a', 'b' => 'b', 'c' => array('d' => 'd', 'e' => 'e'));
$a = array('a' => 'a', 'b' => 'b', 'c' => array('t' => 'd', 'e' => 'e'));

Expected output: 't'

Can someone please give me a clue?

8
  • 1
    Please make a little example from input, current output from your code, and expected output. Commented Aug 17, 2015 at 16:07
  • Okay now we have your current code, but also add e.g. Array1: [1,2,3,2], Array 2: [3,2,3,1,3], current output: xy, expected output: z something like this. Commented Aug 17, 2015 at 16:18
  • Have you read all the answers under "Related" on the right? Commented Aug 17, 2015 at 16:19
  • The arrays are too big. I cannot copy-paste it. The expected result is array of key-value pairs of differences from the original arrays. Commented Aug 17, 2015 at 16:20
  • Yes, I did. Nothing interesting. Commented Aug 17, 2015 at 16:21

1 Answer 1

1

You state that you want recursive differences of keys that works bidirectionally, so given your input:

$a = array('a' => 'a', 'b' => 'b', 'c' => array('d' => 'd', 'e' => 'e'));
$b = array('a' => 'a', 'b' => 'b', 'c' => array('t' => 'd', 'e' => 'e'));

You should get the output:

$output = array('c'=>array('d'=>'d','t'=>'d'));
//or
$output = array('t'=>'d','d'=>'d');

The below method will return the first version of the output. But, you said in your question, that it should just ouput t, which wouldn't make sense because then it could not possibly work bidirectionally (since the key d also does not match).

/** return an array that contains keys that do not match between $array and $compare, checking recursively.
* It's bi-directional so it doesn't matter which param is first
*
* @param $array an array to compare
* @param $compare another array 
*
* @return an array that contains keys that do not match between $array and $compare
*/
function keyMatch($array,$compare){

$output = array();
foreach ($array as $key=>$value){
    if (!array_key_exists($key,$compare)){
        //keys don't match, so add to output array
        $output[$key] = $value;
    } else if (is_array($value)||is_array($compare[$key])){
       //there is a sub array to search, and the keys match in the parent array
        $match = keyMatch($value,$compare[$key]);
        if (count($match)>0){
            //if $match is empty, then there wasn't actually a match to add to $output
            $output[$key] = $match;
        }
    }
}
//Literally just renaiming $array to $compare and $compare to $array
// Why? because I copy-pasted the first foreach loop
$compareCopy = $compare;
$compare = $array;
$array = $compareCopy;
foreach ($array as $key=>$value){
    if (!array_key_exists($key,$compare)){
        $output[$key] = $value;
    } else if (is_array($value)||is_array($compare[$key])){
        $match = keyMatch($value,$compare[$key]);
        if (count($match)>0){
            $output[$key] = $match;
        }
    }
}
return $output;

}
$a = array('a' => 'a', 'b' => 'b', 'c' => array('d' => 'd', 'e' => 'e'));
$b = array('a' => 'a', 'b' => 'b', 'c' => array('t' => 'd', 'e' => 'e'));
print_r(keyMatch($a,$b));

Oh, and here's an example of it working on your small, example input.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.