12
$array = array(1, '1a', '1');
var_export(array_unique($array, SORT_REGULAR));
  • 结果:数组 ( 0 => 1, 2 => '1')
  • 在 PHP 手册中:SORT_REGULAR - 正常比较项目(不要更改类型)。

这背后的逻辑是什么?为什么或如何排除“1a”?

4

2 回答 2

14

发生这种情况的原因array_unique是,首先将值排序为字符串,然后遍历排序后的数组,并为每个值从结果中排除与它相比的所有连续值

上面“比较相等”的比较函数是根据第二个参数来选择的,它SORT_REGULAR与用 的相等性检查相同==

这种行为会引起很多问题。由于排序是快速排序,因此不稳定。因此,对包含两者的数组进行排序,1'1'不能保证哪一个最终会成为结果中的第一个。这意味着在某些情况下和其他情况下array_unique可能会出现任意“偏好” 。1'1'

然而,疯狂仍在继续:考虑如果排序产生[1, '1', '1a']then'1a'不会包含在结果中(它比较等于1),而如果排序产生['1', 1, '1a']则它将包含(它不比较等于字符串'1')!

于 2013-02-10T21:49:21.807 回答
4

如果您想获得更多技术信息,可以查看源代码。

PHP_SORT_REGULAR标志只是告诉array_unique回退到标准比较运算符 ( ==)。

您可以在array_unique使用的源代码中看到这一点php_set_compare_func

static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */
{
switch (sort_type & ~PHP_SORT_FLAG_CASE) {
...
    case PHP_SORT_REGULAR:
    default:
        ARRAYG(compare_func) = compare_function;
        break;
} 

哪里compare_func只是标准比较功能

这可能是一个文档错误,而不是其他任何东西。文档中的评论有点误导:

...当且仅当 (string) $elem1 === (string) $elem2

如果两个值都转换为字符串,则不需要,但它会导致进行类型比较===的假设。SORT_REGULAR

于 2013-02-10T21:59:35.747 回答