PHP基于子数组元素的usort数组不能正常工作-bug



这是我当前的代码,使用php 7.1.20-1+ubuntu18.04.1+deb.sury.org.1:(按四列排序,第五列仅为子阵列参考号。(

$dud = [[2,3,"2018-07-19","08:23",1],
[2,3,"2018-07-19","08:30",2],
[2,1,"2018-07-19","08:14",3],
[2,4,"2018-07-19","07:11",4],
[2,1,"2018-07-19","07:17",5],
[2,9,"2018-07-19","07:31",6],
[2,4,"2018-07-19","05:06",7],
[2,6,"2018-07-18","08:10",8],
[2,9,"2018-07-19","07:20",9],
[1,7,"2018-07-19","08:27",10],
[1,5,"2018-07-19","08:11",11],
[1,7,"2018-07-18","08:22",12],
[1,5,"2018-07-19","08:09",13],
[2,6,"2018-07-18","07:12",14],
[1,7,"2018-07-18","08:21",15],
[1,7,"2018-07-19","07:09",16]];
usort($dud, function($a,$b){if ($a[3] !== $b[3]){return strcmp($a[3],$b[3]);}});
usort($dud, function($a,$b){if ($a[2] !== $b[2]){return strcmp($a[2],$b[2]);}});
// usort($dud, function($a,$b){if ($a[1] !== $b[1]){return $a[1] - $b[1];}});
usort($dud, function($a,$b){if ($a[1] !== $b[1]){return strcmp($a[1],$b[1]);}});
// usort($dud, function($a,$b){if ($a[0] !== $b[0]){return $a[0] - $b[0];}});
usort($dud, function($a,$b){if ($a[0] !== $b[0]){return strcmp($a[0],$b[0]);}});
foreach($dud as $output){
foreach($output as $output2){
echo "  $output2   ";
}
echo "<br/>";
}

我正在尝试对16个子数组进行排序,先按第4列,然后按第3列,再按第2列,然后是第1列。我的输出:

1 5 2018-07-19 08:09 13
1 5 2018-07-198 08:11 11
17 2018-07-18 08:21 15
11 7 2018-07-1907 07:09 16
10 2018-07-1908 08:27 10
2 1 2018-07-1909 08:14 3
21 2018-07-19807 07:17 5
23 2018-07-1908:23 1
22 32018-07-19 08:30 2
2 4 2018-07-1907:11 4
22 4 2018-0719 05:06 7
24 2018-07-18 08:10 8
26 2018-07-18 07:12 14
29 2018-07-1907 07:20 9
20 9 2018-0719 07:31 6

照原样,输出中的子阵列3和5出现了无序(07:17应在08:14之前(,子阵列4和7出现了无序的情况(05:06应在07:11之前(,并且子阵列8和14出现了无序情况(07:12应在08:10之前(。注释掉不同的usort行,它将第四列与注释掉的所有其他usort行进行了很好的排序。仅对第1列和第4列进行排序效果良好。只对第2列和第4列进行排序,子数组3和5就乱了序(07:17应该在8:14之前(。只对第3列和第4列进行排序,子数组8和14就乱了序(07:12应该在08:10之前(。知道这里发生了什么吗?我已尝试利用以下位置的可用信息:PHP按子数组值对数组排序但在第四栏中仍然出现了一个古怪的失误。非常感谢!!

在PHP7中,飞船操作员进行了多次比较。

将您的条件声明为两个平衡数组中的数组元素——三元运算符将为您进行巧妙的排序。

代码:(演示((新演示(

函数sort3210ASC($a,$b({
if($a3!==$b3

function sort3210ASC($a, $b) {
return [$a[3], $a[2], $a[1], $a[0]]
<=>
[$b[3], $b[2], $b[1], $b[0]];
}
usort($dud, 'sort3210ASC');
var_export($dud);

如果我要编写一种多端口方法,我会利用array_column()而不是foreach()循环来生成临时列阵列。虽然循环可能是微观优化的选项,但array_column()为未来的代码阅读器(人类(提供了一个更容易理解的片段。

代码:(演示(

array_multisort(
array_column($dud, 3),
array_column($dud, 2), 
array_column($dud, 1), 
array_column($dud, 0), 
$dud
);  
var_export($dud);
// sorts $dud by column 3 then 2 then 1 then 0

感谢mickmackusa,试用您的解决方案,我将其个性化为:

usort($dud, function($a,$b){
if ($a[0] !== $b[0]) return $a[0] > $b[0];
if ($a[1] !== $b[1]) return $a[1] > $b[1];
if ($a[2] !== $b[2]) return $a[2] > $b[2];
if ($a[3] !== $b[3]) return $a[3] > $b[3];
return 0;
});

显然,在进行四种不同的排序时,其中一种更改了以前的排序,甚至使用了!==比较运算符,但你把它们放在一起的解决方案成功了。非常感谢!!

最新更新