user785533
user785533

Reputation:

Filter rows of a 2d array by the rows in another 2d array

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']
]

Upvotes: 1

Views: 1534

Answers (3)

mickmackusa
mickmackusa

Reputation: 47992

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',
  ),
)

Upvotes: 0

Neeraj
Neeraj

Reputation: 9175

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 ) ) .

Upvotes: 1

Amber
Amber

Reputation: 527063

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 )).

Upvotes: 6

Related Questions