1

I have two arrays, and I am using array_diff_assoc() to get the difference, but it always returns the common set row in the result

It should be returning the new q sets row. What's wrong with my approach?

Sample data:

$array1 = [
    [12 => 'new q sets'],
    [11 => 'common set']
]

$array2 => [
    [11 => 'common set']
];

After calling array_diff_assoc($array1, $array2), my output is:

[
    [11 => 'common set']
]
mickmackusa
  • 43,625
  • 12
  • 83
  • 136

3 Answers3

6

Two values from key => value pairs are considered equal only if (string) $elem1 === (string) $elem2 . In other words a strict check takes place so the string representations must be the same.

http://php.net/manual/en/function.array-diff-assoc.php

The (string) value of any array is "Array". Thus, your call to array_diff_assoc is effectively comparing these two things:

Array ( [0] => "Array" [1] => "Array" ) 
Array ( [0] => "Array" ) 

Since the thing that is different between those two is the [1] key/value pair from the first array, you get that back ([1] => Array( [11] => common set )).

Amber
  • 507,862
  • 82
  • 626
  • 550
  • @Suneth Put the 2nd array in as the first variable in the array_diff_assoc() function. – Nick Mar 27 '12 at 08:14
  • @Suneth Don't use `array_diff_assoc()`. It's not designed for what you're trying to do. – Amber Mar 27 '12 at 16:28
1

in array_diff_assoc(), keys are also compared. Since [0] is available in second array and [1] is not available in second array so thats why the result is Array ( [1] => Array ( [11] => common set ) ) .

Neeraj
  • 8,625
  • 18
  • 60
  • 89
0

When running your script in a modern php environment, the Warnings should indicate that you are using the wrong tool for the job.

Bad Code: (Demo)

$array1 = [[12 => 'new q sets'], [11 => 'common set']];
$array2 = [[11 => 'common set']];

var_export(array_diff_assoc($array1, $array2));

Bad Output:

Warning: Array to string conversion in /in/jIUcq on line 6

Warning: Array to string conversion in /in/jIUcq on line 6
array (
  1 => 
  array (
    11 => 'common set',
  ),
)

You don't actually want to compare the first level indexes anyhow because related/matching rows may have different first level indexes.


Instead, you should use array_udiff() to compare the associative rows (and ignore the first level keys). Making a 3-way comparison -- as array_udiff() expects from the callback -- without iterated function calls is possible with the "spaceship operator". In the below snippet, $a and $b represent rows of data.

Proper Code: (Demo)

var_export(
    array_udiff($array1, $array2, fn($a, $b) => $a <=> $b)
);

Proper Output:

array (
  0 => 
  array (
    12 => 'new q sets',
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136