PHP 基于子数组元素的 usort 数组不能正常工作 - 错误?
PHP usort array based on subarray elements not working right - buggy?
这是我当前的代码,使用 php 7.1.20-1+ubuntu18.04.1+deb.sury.org+1:
(四列排序,第 5 列只是一个子数组参考编号。)
$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-19 08:11 11
1 7 2018-07-18 08:21 15
1 7 2018-07-18 08:22 12
1 7 2018-07-19 07:09 16
1 7 2018-07-19 08:27 10
2 1 2018-07-19 08:14 3
2 1 2018-07-19 07:17 5
2 3 2018-07-19 08:23 1
2 3 2018-07-19 08:30 2
2 4 2018-07-19 07:11 4
2 4 2018-07-19 05:06 7
2 6 2018-07-18 08:10 8
2 6 2018-07-18 07:12 14
2 9 2018-07-19 07:20 9
2 9 2018-07-19 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 Sort Array By SubArray Value
但在第四列中仍然出现古怪的古怪错误。
非常感谢!!
从PHP7开始,飞船算子把多重比较做的很整齐
将您的条件声明为两个平衡数组中的数组元素——三向运算符将为您进行巧妙的排序。
函数 sort3210ASC($a, $b) {
如果 ($a3 !== $b3) return $a3 <=> $b3;
如果 ($a3 !== $b3) return $a3 <=> $b3;
如果 ($a1 !== $b1) return $a1 <=> $b1;
如果 ($a[0] !== $b[0]) return $a[0] <=> $b[0];
return 0;
}
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()
为未来的代码阅读者(人类)提供了一个更易于理解的片段。
代码:(Demo)
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;
});
显然进行了四种不同的排序,其中一种改变了之前的排序,即使使用了 !== 比较运算符,但是您将它们放在一种排序中的解决方案也成功了。非常感谢!!
这是我当前的代码,使用 php 7.1.20-1+ubuntu18.04.1+deb.sury.org+1: (四列排序,第 5 列只是一个子数组参考编号。)
$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-19 08:11 11
1 7 2018-07-18 08:21 15
1 7 2018-07-18 08:22 12
1 7 2018-07-19 07:09 16
1 7 2018-07-19 08:27 10
2 1 2018-07-19 08:14 3
2 1 2018-07-19 07:17 5
2 3 2018-07-19 08:23 1
2 3 2018-07-19 08:30 2
2 4 2018-07-19 07:11 4
2 4 2018-07-19 05:06 7
2 6 2018-07-18 08:10 8
2 6 2018-07-18 07:12 14
2 9 2018-07-19 07:20 9
2 9 2018-07-19 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 Sort Array By SubArray Value 但在第四列中仍然出现古怪的古怪错误。 非常感谢!!
从PHP7开始,飞船算子把多重比较做的很整齐
将您的条件声明为两个平衡数组中的数组元素——三向运算符将为您进行巧妙的排序。
函数 sort3210ASC($a, $b) {
如果 ($a3 !== $b3) return $a3 <=> $b3;
如果 ($a3 !== $b3) return $a3 <=> $b3;
如果 ($a1 !== $b1) return $a1 <=> $b1;
如果 ($a[0] !== $b[0]) return $a[0] <=> $b[0];
return 0;
}
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()
为未来的代码阅读者(人类)提供了一个更易于理解的片段。
代码:(Demo)
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;
});
显然进行了四种不同的排序,其中一种改变了之前的排序,即使使用了 !== 比较运算符,但是您将它们放在一种排序中的解决方案也成功了。非常感谢!!