Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About array_udiff,I want to ask again [closed]

Tags:

php

2 days ago,I have asked this question ( I am confused on the issue,how to use array_udiff ).
I'm sorry to discuss this question once again.
Although I have got the solution to the problem, but I'm still confused on this question:
demo1:

function myfunction($v1,$v2) 
{
if ($v1===$v2)
    {
    return 0;
    }
return 1;
}
$a1=array("a"=>"Cat","b"=>"Dog","c"=>"Horse");
$a2=array(1=>"Cat",2=>"Dog",3=>"Fish");
print_r(array_udiff($a1,$a2,"myfunction"));

output:

Array ( [c] => Horse )

demo2:

function myfunction($v1,$v2) 
{
if ($v1===$v2)
    {
    return 0;
    }
return 1;
}
$a1 = array(1,2,3,4,5);
$a2 = array(1,6,3,4,5);
print_r(array_udiff($a1,$a2,"myfunction"));

I expect this to return:

Array ( [0] => 2 )

but the output is:

Array ( [0] => 1 [1] => 2 [2] => 3 [4] => 5 )

Yes,I know, I need to according to the php manual,
demo3:

function myfunction($v1,$v2) {
    if ($v1 < $v2) {
        return -1;
    } elseif ($v1 > $v2) {
        return 1;
    } else {
        return 0;
    }
}
$a1 = array(1,2,3,4,5);
$a2 = array(1,6,3,4,5);
print_r(array_udiff($a1,$a2,"myfunction"));

output:

Array ( [1] => 2 )// it's right

What I am confused is that why the demo1 is ok.

like image 334
ZhouMengkang Avatar asked Jan 13 '14 15:01

ZhouMengkang


1 Answers

The result you're getting is because you're using callback which returns 1 and 0. While logically it's justified (i.e. 1 means "equal" and 0 means "not equal") - PHP expects callback that return full comparison - thus, not only on equality - but also greater and less comparison.

To understand why it is so you need to understand how PHP processes calculation of arrays difference. It's not just simple walking through both arrays. PHP will sort arrays first, then will do checks. That is because simple walk (nested loop) will result in O(n*m) complexity, while sorting arrays first will result in approximately O(k log(k)), k=max(n, m) complexity for two arrays of size n and m. And to sort elements via user-defined callback it's not enough to check elements equality. You'll need to know their order, that's why less/greater comparison is needed.

So, as a conclusion: you can only use callback with full -1/0/1 values in it's result. If your callback returns something different, results will be unpredictable - that's why they may be "correct" and "wrong" on different input data.

like image 138
Alma Do Avatar answered Sep 18 '22 10:09

Alma Do