$array = array(1, '1a', '1');
var_export(array_unique($array, SORT_REGULAR));
- 结果:数组 ( 0 => 1, 2 => '1')
- 在 PHP 手册中:SORT_REGULAR - 正常比较项目(不要更改类型)。
这背后的逻辑是什么?为什么或如何排除“1a”?
$array = array(1, '1a', '1');
var_export(array_unique($array, SORT_REGULAR));
这背后的逻辑是什么?为什么或如何排除“1a”?
发生这种情况的原因array_unique
是,首先将值排序为字符串,然后遍历排序后的数组,并为每个值从结果中排除与它相比的所有连续值。
上面“比较相等”的比较函数是根据第二个参数来选择的,它SORT_REGULAR
与用 的相等性检查相同==
。
这种行为会引起很多问题。由于排序是快速排序,因此不稳定。因此,对包含两者的数组进行排序,1
并'1'
不能保证哪一个最终会成为结果中的第一个。这意味着在某些情况下和其他情况下array_unique
可能会出现任意“偏好” 。1
'1'
然而,疯狂仍在继续:考虑如果排序产生[1, '1', '1a']
then'1a'
将不会包含在结果中(它比较等于1
),而如果排序产生['1', 1, '1a']
则它将被包含(它不比较等于字符串'1'
)!
如果您想获得更多技术信息,可以查看源代码。
该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