0

I'm trying to find the difference between two multi-dimensional associative arrays. Specifically any elements in the first array that are no present or different in the second array only. Not the other way around. Hence, 'y'=>1 is not part of the result.

$arra = ['x'=>1, 'y'=>1, 'z'=>1, 'add'=>['a'=>1]];
$arrb = ['x'=>2, 'y'=>1, 'add'=>[]];

To get this result:

['x'=>1, 'z'=>1, 'add'=>['a'=>1]];

I can use array_diff_assoc($arra, $arrb) if the arrays are 1D.

But is there something I can use to handle the inner array 'add'?

I can write my own function to recursively look through the array, but is there something simpler available?

Thanks.

EDIT: Using @abracadaver's answer, I tried

function sortAndSerialize($arr){
    ksort($arr);
    return serialize($arr);
}

array_map('unserialize', array_diff(array_map('sortAndSerialize', [$arra]), array_map('sortAndSerialize', [$arrb])));

But it returns the following

Array ( [0] => Array ( [add] => Array ( [a] => 1 ) [x] => 1 [y] => 1 [z] => 1 ) )

Note: I updated my original array so it has identical and different elements.

The question isn't a duplicate. The other question uses an array where each element is an array. In this case, the elements may be arrays or strings etc. The other solution doesn't work here.

EDIT2: AbraCadaver answer:

$result = array_filter($arra, function($v, $k) use($arrb) { return (!isset($arrb[$k]) || $arrb[$k] !== $v); }, ARRAY_FILTER_USE_BOTH);

works well for my original arrays which are associative.

It doesn't work if the arrays are indexed however. For example:

$arra = ['x'=>1, 'y'=>1, 'z'=>1, 'add'=>[3,5]];
$arrb = ['x'=>2, 'y'=>1, 'add'=>[3]];

This returns:

['x'=>1, 'z'=>1, 'add'=>[3,5]];

Instead of:

['x'=>1, 'z'=>1, 'add'=>[5]];

Basically anything inside a non-assc array is not compared and entire contents are returned, unless identical.

It would help to look into how to get it to work for both associative and non-associative arrays.

fractal5
  • 2,034
  • 4
  • 29
  • 50
  • 1
    https://stackoverflow.com/questions/22354767/use-array-diff-assoc-or-get-difference-of-multidimensional-arrays/22355153#22355153 – AbraCadaver Jul 24 '18 at 18:00
  • Thanks. That doesn't work if I directly use it on $arra and $arrb. But if I insert each of $arra and $arrb into an array, it works perfectly, which is even better for my case. – fractal5 Jul 24 '18 at 18:07
  • Why isn't "y" => 1 a difference? – Andreas Jul 24 '18 at 18:29
  • I updated the question. Only looking for elements that are present in the first array. Thanks for catching that. – fractal5 Jul 24 '18 at 18:31
  • @AbraCadaver Looks like I was too hasty with my testing. Your answer, even with sortAndSerialize returns all the elements in first array, even the ones that are the same as the second array. It only works if the arrays are identical, in which case it returns an empty array. – fractal5 Jul 24 '18 at 18:41
  • @AbraCadaver Updated my question to include result from your answer – fractal5 Jul 24 '18 at 18:48
  • The answer here works perfectly. https://stackoverflow.com/a/29526501/4594387 – fractal5 Jul 24 '18 at 19:22
  • 1
    I closed this and then reopened as duplicate doesn't work for this array. Play with this `$result = array_filter($arra, function($v, $k) use($arrb) { return (!isset($arrb[$k]) || $arrb[$k] !== $v); }, ARRAY_FILTER_USE_BOTH);` – AbraCadaver Jul 24 '18 at 19:24
  • Thanks, that works very well. Can the question be reopened so this can be posted as answer? – fractal5 Jul 25 '18 at 13:22
  • @AbraCadaver Your answer works well for associative arrays (my original question) but not for indexed ones. I added an edit to my question to explain this. Trying to understand how I can apply it to both kinds of arrays. Thanks for your help so far though. – fractal5 Jul 25 '18 at 13:37

0 Answers0