array_udiff 似乎不起作用

Kri*_*ofe 2 php arrays array-difference

我正在尝试将两个数组与 array_udiff 进行比较,但它非常奇怪。似乎 array_udiff 没有得到正确的答案。这是现场演示。结果应该是一个空数组,但留下一个未过滤的元素。

<?php

$string = '{
  "sakiniai": [

      {
        "Faktas": "A",
        "value": "true"
      },
      {
        "Faktas": "B",
        "value": "true"
      },
      {
        "Faktas": "A",
        "value": "false"
      }
  ]
}';

$sakiniais = json_decode($string, true)['sakiniai'];


$v = $sakiniais[0];
$arr[] = $v;
$v['value'] = $v['value'] == "true" ? "false" : "true";
$arr[] = $v;
var_dump($arr);
var_dump($sakiniais);


print_r(array_udiff($arr, $sakiniais, function($a, $b){
/*
var_dump($a);
var_dump($b);
var_dump($a == $b);
echo "\n\n\n";
*/
return $a == $b ? 0 : -1;}
));
Run Code Online (Sandbox Code Playgroud)

输出

    array(2) {
  [0]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
  }
  [1]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
  }
}
array(3) {
  [0]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
  }
  [1]=>
  array(2) {
    ["Faktas"]=>
    string(1) "B"
    ["value"]=>
    string(4) "true"
  }
  [2]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
  }
}
Array
(
    [1] => Array
        (
            [Faktas] => A
            [value] => false
        )

)
Run Code Online (Sandbox Code Playgroud)

Lom*_*baX 8

问题是 array_udiff 没有执行所有值之间的比较,这似乎是由您的比较函数引起的。

array_udiff() 期望可调用函数是一个真正的比较函数,但您总是返回 0 和 -1,但从不返回 1。

在完成工作之前,array_udiff() 尝试对两个数组进行排序并删除重复项。如果它不能依赖你的比较函数,它就不能执行所有需要的比较,并且某些值会“跳跃”。

查看文档中的所有注释,特别napcoder 注释

请注意,compare 函数也在内部使用,用于对数组进行排序并选择下一轮比较的元素。

如果您的比较函数不是真正的比较(即,如果元素相等则返回 0,否则返回 1),您将收到意外结果。

这是通过查看您的数组来证明的

$arr

array(2) {
  [0]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
  }
  [1]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
  }
}
Run Code Online (Sandbox Code Playgroud)

和 $sakiniis

array(3) {
  [0]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
  }
  [1]=>
  array(2) {
    ["Faktas"]=>
    string(1) "B"
    ["value"]=>
    string(4) "true"
  }
  [2]=>
  array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
  }
}
Run Code Online (Sandbox Code Playgroud)

您应该期望测试两个数组之间的所有组合,但测试的组合(如下)不包括 A-False 与 A-False

array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
}
array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
}
bool(false)



array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
}
array(2) {
    ["Faktas"]=>
    string(1) "B"
    ["value"]=>
    string(4) "true"
}
bool(false)



array(2) {
    ["Faktas"]=>
    string(1) "B"
    ["value"]=>
    string(4) "true"
}
array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
}
bool(false)



array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
}
array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
}
bool(true)



array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(4) "true"
}
array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
}
bool(false)



array(2) {
    ["Faktas"]=>
    string(1) "A"
    ["value"]=>
    string(5) "false"
}
array(2) {
    ["Faktas"]=>
    string(1) "B"
    ["value"]=>
    string(4) "true"
}
bool(false)
Run Code Online (Sandbox Code Playgroud)

这篇文章的正确答案中,还有一些关于 array_udiff 如何工作的有用见解

您可以像这样更改退货声明

if ($a < $b) {
    return -1;
} elseif ($a > $b) {
    return 1;
} else {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(如果您想知道如何比较两个数组的较小/较大,请查看此链接,在“与各种类型的比较”部分和“标准数组比较的示例#2 转录”示例中)