首页 > 解决方案 > array_udiff 不应该为我的两个数组的每次迭代调用我的函数吗?

问题描述

在 php 7.3 上运行

在有人问之前,我已经测试了我的比较功能,它似乎工作得很好。如果compare($a, $b)为 1,compare($b, $a)则为 -1。如果相等,则倒数仍然相等。下面的“对象”都属于同一类。

class myObject(){
    private $a;
    private $b;
    private $c;
    private $d;

    public function __construct($a, $b, $c, $d){
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
        $this->d = $d;
    }

    public static function compare(myObject $object_1, myObject $object_2){
         //This is somewhat complicated but my tests show that it works.
         return $result; // -1, 0. or 1
    }

    public function hasTwoNulls(){
        return $this->c === null && $this->d === null;
    }
}

$object_1 = new myObject('string', 'string', null, null);
$object_A = new myObject('string', 'string', null, null);
//etc....

$array_1 =[ $object_1, $object_2, //etc...];
$array_2 =[ $object_A, $object_B, //etc...];

$diff = array_udiff(
            $array_1,
            $array_2,
            static function( $a, $b ) {
                if($a->hasTwoNulls() && $b->hasTwoNulls()){
                    print 'I have a breakpoint on this line that is never reached!!!.';
                }
                return myObject::compare( $a, $b);  
            }
        );


如上所述,我在每个对象中测试两个空值的断点从未到达,即使它应该到达。我很困惑为什么它从不一起测试这些对象,为什么即使myObject::compare( $a, $b);我得到 0 的对象也总是在我的 $diff 中结束,也就是相等。

似乎它在不使用我的回调的情况下进行某种比较。有人读过这个法术吗?

标签: phparraysoop

解决方案


array_udiff()显然有一些优化以避免比较每一对元素。我不确定确切的算法,但我认为它是对两个数组进行排序并删除重复项,然后逐步遍历它们以找到匹配的元素。

您可以通过一个更简单的示例看到这一点

$array1 = [1, 2, 3];
$array2 = [4, 5, 6];
var_dump(array_udiff($array1, $array2, function($a, $b) {
  echo "Comparing $a and $b<br>";
  if ($a < 4 && $b < 4) {
    return 0;
  } elseif ($a > 3 && $b > 3) {
    return 0;
  } else {
    return rand(-1, 1);
  }
}));

产生:

Comparing 1 and 2
Comparing 2 and 3
Comparing 4 and 5
Comparing 5 and 6
Comparing 1 and 4
Comparing 1 and 5
Comparing 1 and 6
Comparing 1 and 2
Comparing 2 and 3
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

推荐阅读