基于子数组元素的PHP usort数组无法正常工作-越野车?

时间:2018-08-03 17:01:15

标签: php arrays sorting multidimensional-array sub-array

这是我当前的代码,使用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列,然后是2nd,然后是1st。我的输出:

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行,它将第4列与其他所有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 但在第四栏中仍然出现了古怪的奇怪问题。 非常感谢!

2 个答案:

答案 0 :(得分:1)

您的样本输入数据在表示比较中的“联系”方面相当无效,但是排序的逻辑将要求您在出现联系时对其进行拆分。我会建议以下条件级联:

代码:(Demo

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

$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, 'sort3210ASC');
var_export($dud);

如果我要编写一种多排序方法,我将利用array_column()而不是foreach()循环来生成临时列式数组。尽管循环可能是经过微优化的选项,但是array_column()为将来的代码阅读器(人员)提供了更容易理解的摘录。

代码:(Demo

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

答案 1 :(得分: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;
});

显然,它进行了四种不同的排序,即使使用!==比较运算符,它们中的一种也改变了以前的排序,但是您将它们归为一类的解决方案就可以了。非常感谢!