### Result of sort
sort($keys_arranged, SORT_NUMERIC);
var_dump($keys_arranged);
{ ...
[51]=> float(11.903327742296)
[52]=> int(5)
[53]=> float(13.165002546636)
[54]=> float(14.478273306964)
[55]=> float(4.6264742674547)
[56]=> float(13.290508819344)
[57]=> float(15.686809055276) }
### Result or rsort
rsort($keys_arranged, SORT_NUMERIC);
var_dump($keys_arranged);
{
[0]=> float(15.686809055276)
[1]=> float(14.478273306964)
[2]=> float(13.290508819344)
[3]=> float(13.165002546636)
[4]=> float(11.903327742296)
[5]=> int(5)
[6]=> float(4.6264742674547)
... }
echo var_export($keys_arranged);
array ( 0 => 3.142678516658294, 1 => 1.0, 2 => 1.0, 3 => 14.478273306963985, 4 => 13.165002546635966, 5 => 1.0, 6 => 1.0005037081114851, 7 => 1.0, 8 => 4.6264742674547001, 9 => 15.686809055275578, 10 => 1.0, 11 => 11.903327742295504, 12 => 13.29050881934397, 13 => 1.0, 14 => 1.0, 15 => 3.5421134937189365, 16 => 1.0, 17 => 0.010999999999999999, 18 => 3.2999566681750605, 19 => 5, 20 => 1.2282984802843129, 21 => 1.0, 22 => 2.9748253120971184, 23 => 0.44855992975075798, 24 => 0.99999999999999989, 25 => 3.8350475954623371, 26 => 1.0625975061426283, 27 => 1.0000072792091179, 28 => 0.99999987785487132, 29 => 1, 30 => 0.0, 31 => 1.0, 32 => 1.0, 33 => 1.0, 34 => 0.0, 35 => 1.0972568578553616, 36 => 1.0, 37 => 1.4077661823957415, 38 => 1.0, 39 => 0.0, 40 => 3.6038030347555705, 41 => 1.0, 42 => 1.0, 43 => 1.0636876768842174, 44 => 1.0, 45 => NAN, 46 => 1.0, 47 => NAN, 48 => NAN, 49 => NAN, 50 => NAN, 51 => 1.0, 52 => 1.0, 53 => NAN, 54 => 0.99958680716631509, 55 => 1.0, 56 => NAN, 57 => 1.0, )
我从array_multisort得到了一些不正确的结果。它有8个不同的键和所有键,但是此键(例如A)可以正常工作。
要弄清楚为什么会发生这种情况,我在数组中使用了A。而且我不仅可以在array_multisort函数中看到,而且在'sort'函数中也可以看到错误的结果。
如您所见,rsort的结果似乎还可以,但sort的结果在 13.16 <14.47 <4.62 <13.29 <15.68
有人知道为什么会这样吗?
// Data in readible format
array (
0 => 3.142678516658294,
1 => 1.0,
2 => 1.0,
3 => 14.478273306963985,
4 => 13.165002546635966,
5 => 1.0,
6 => 1.0005037081114851,
7 => 1.0,
8 => 4.6264742674547001,
9 => 15.686809055275578,
10 => 1.0,
11 => 11.903327742295504,
12 => 13.29050881934397,
13 => 1.0,
14 => 1.0,
15 => 3.5421134937189365,
16 => 1.0,
17 => 0.010999999999999999,
18 => 3.2999566681750605,
19 => 5,
20 => 1.2282984802843129,
21 => 1.0,
22 => 2.9748253120971184,
23 => 0.44855992975075798,
24 => 0.99999999999999989,
25 => 3.8350475954623371,
26 => 1.0625975061426283,
27 => 1.0000072792091179,
28 => 0.99999987785487132,
29 => 1,
30 => 0.0,
31 => 1.0,
32 => 1.0,
33 => 1.0,
34 => 0.0,
35 => 1.0972568578553616,
36 => 1.0,
37 => 1.4077661823957415,
38 => 1.0,
39 => 0.0,
40 => 3.6038030347555705,
41 => 1.0,
42 => 1.0,
43 => 1.0636876768842174,
44 => 1.0,
45 => NAN,
46 => 1.0,
47 => NAN,
48 => NAN,
49 => NAN,
50 => NAN,
51 => 1.0,
52 => 1.0,
53 => NAN,
54 => 0.99958680716631509,
55 => 1.0,
56 => NAN,
57 => 1.0, )
答案 0 :(得分:1)
似乎您确实发现了一个错误。在包含NaN
值的大型数组上(由PHP中的NAN
常量表示),内置函数sort
失败。
与NaN
的比较应始终如问题注释中的 kuh-chan 所提到的那样是无序的。但是,一旦存在至少一个操作数NaN
,在最新的PHP版本(2019年3月)中,太空飞船操作符<=>
返回1
(第一个操作数大于第二个操作数)和-1
(第一个操作数小于第二个操作数)。
echo var_dump( NAN <=> 1.23 );
echo var_dump( 1.23 <=> NAN );
echo var_dump( NAN <=> -1.23 );
echo var_dump( -1.23 <=> NAN );
echo var_dump( NAN <=> 0 );
echo var_dump( NAN <=> NAN );
我对Zend引擎的内部并不十分熟悉。但是,我猜想sort
算法在具有几个NaN
值的大型数组上终止太早了,可能是为了顺序比较算法总是返回“大于(或小于)”,这可能导致多次交换相同的元素。
我经历了多次调用sort
似乎可以继续进行排序的过程。但是,那不是一个适当的解决方法。
您可以将自定义比较算法与usort
一起使用。如果要在数组的开头对NaN
进行排序,则当第一个操作数为-1
时返回NaN
,当第二个操作数为1
时返回NaN
0
(等于)(如果两者都是)。否则,返回航天器运算符的比较结果。
usort($keys_arranged,
function(&$v1, &$v2)
{
switch( (is_nan($v1) ? 1 : 0) | (is_nan($v2) ? 2 : 0) )
{
case 0: return $v1 <=> $v2;
case 1: return -1;
case 2: return 1;
case 3: return 0;
}
}
);
与上述类似的按位逻辑,但压缩性和直接性更高:
usort( $keys_arranged,
function(&$v1, &$v2){ return -2 === ($b = (is_nan($v1) ? -1 : -2) ^ (is_nan($v2) ? -1 : 0)) ? $v1 <=> $v2 : $b; }
);