2

I have the following simple function to try and understand the array_udiff() function

function udiffCompare( $value, $value2 )
{

echo $value . " - " . $value2 . "<br />";

}

$newArray   =   array(  

                    'value2' => 2, 
                    'value3' => 3, 
                    'value4' => 4
                );

$newArray2  =   array(  

                    'value2' => 2, 
                    'value3' => 3, 
                    'value4' => 4
                );

array_udiff( $newArray, $newArray2, 'udiffCompare' );

I would expect this to simply return:

2 - 2
3 - 3
4 - 4

However it returns:

3 - 2
4 - 3
3 - 2
4 - 3
4 - 4
4 - 3
4 - 3
3 - 2

This leads me to believe there is something I am really not understanding here about how array_udiff() works.

Even if I replace the echo statement above with:

if( $value == $value2 ) { return 1; } else { return 0; }

the outputted array is completely empty even though all the values passed to the function are equal.

Could someone shine a light please?

Peter Featherstone
  • 7,171
  • 4
  • 27
  • 62
  • http://stackoverflow.com/questions/10271708/how-does-array-udiff-work – underscore Jul 01 '13 at 10:01
  • 1
    Even if I add if( $value == $value2 ) { return 1; } else { return 0; } it still returns a massive list of different numbers which means my outputted array is completely empty even though all the values are equal. – Peter Featherstone Jul 01 '13 at 10:06
  • Your callback function is to blame: `int callback ( mixed $a, mixed $b )` should be its signature. Though I'd say `array_map` or `list` is a better fit for your use-case – Elias Van Ootegem Jul 01 '13 at 10:08
  • This here is about *sorting* arrays, but the basic concept of a comparison function is the same: http://stackoverflow.com/a/17364128/476 Read for more of a conceptual introduction. – deceze Jul 01 '13 at 10:21

2 Answers2

3

array_udiff computes the difference of the two arrays. That is all entries in $newArray which are not in $newArray2. In this case the result is an empty array because there is no difference.

The output you are seeing is because you are echoing each value that is being compared. The reason this is a larger list is because, in order to find out the difference array_udiff has to compare every value in $newArray with every value in $newArray2.

Jim
  • 21,521
  • 5
  • 49
  • 80
  • Ah right, ok that makes sense about why I am seeing the long list now to a point... However it still doesn't seem to compare the first value of "2" with anything and the comparison 3 - 2 is made 3 times? What doesn't make sense is why replacing the echo statement with `if( $value == $value2 ) { return 1; } else { return 0; }` is returning a blank array? – Peter Featherstone Jul 01 '13 at 10:12
  • It's returning a blank array because there is no difference in the two arrays. Because there is no difference there is nothing to return. Try adding another value to `$newArray` only. – Jim Jul 01 '13 at 10:13
  • Ok... I wasn't aware a blank array would be returned if they were blank... I was under the assumption that it would just return any values that are similar in the arrays... Adding another value to the first array made it return as expected... Thanks for the help Jim! – Peter Featherstone Jul 01 '13 at 10:15
  • From the manual: "The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second." (i.e. you're returning the wrong value when $a – symcbean Jul 01 '13 at 10:15
  • Ok, no I dont think I quite understand it still after further playing... If I compare 2 arrays one with the values `1,2,3` and the other with values `1,2,3,4,5` and run a simple `if( $value == $value2 ) { return 0; } return 1;` in the callback function why does it return just 2 and 3? Would it not either return 1,2,3 or 4,5... I dont understand why it returns just 2,3... – Peter Featherstone Jul 01 '13 at 10:45
  • @PeterFeatherstone It should return an empty array if 1,2,3 is the first array and 4,5 if 1,2,3,4,5 is the first array. As symcbean mentioned your callback function should return positive and negative numbers depending on whether `$a>$b` or `$a – Jim Jul 01 '13 at 10:55
  • So it is basically not for comparing equal values but rather non-equal? So I should change the `$value == $value2` for `$value > $value2` for example? What about using a negative equals comparision `$value != $value2`? – Peter Featherstone Jul 01 '13 at 11:11
  • Yes it's for returning values in the first array which aren't in the second. If you want values in either array you can use `array_merge` or for values in both arrays `array_intersect`. A callback method may do something like: `return $value - $value2;` Which will return positive or negative depending on the values. – Jim Jul 01 '13 at 11:51
1

You didn't write proper callback function for array_udiff().

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

Moreover mathematical difference of these 2 sample arrays you given is NULL That is why you will get empty result set if you use this function. Check it on array_diff();

The gray area shows the difference of two collections:

enter image description here

Robert
  • 17,808
  • 4
  • 50
  • 79