Here's my current code, using php 7.1.20-1+ubuntu18.04.1+deb.sury.org+1: (Four columns to sort by, 5th column just a subarray reference number.)
$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/>";
}
I am attempting to sort the 16 subarrays, first by 4th column, then by 3rd column, then 2nd, then 1st. My output:
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
As is, the output has subarrays 3 and 5 out of order (07:17 should be before 08:14), subarrays 4 and 7 are out of order (05:06 should be before 07:11), and subarrays 8 and 14 are out of order (07:12 should be before 08:10). Commenting out different usort lines, it sorts column four just fine with all other usort lines commented out. Sorting just columns 1 and 4 works fine. Sorting just columns 2 and 4, subarrays 3 and 5 are out of order (07:17 should be before 8:14). Sorting just columns 3 and 4, subarrays 8 and 14 are out of order (07:12 should be before 08:10). Any idea what's going on here? I've tried making use of what info is available at: PHP Sort Array By SubArray Value but still getting a quirky oddball missort in the fourth column. Thanks much!!
Your sample input data is rather ineffective in representing "ties" in comparisons, but the logic of your sorting will require you to split ties as they arise. I'll advise the following cascading conditional:
Code: (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);
If i was to write a multisort approach, I would leverage array_column()
instead of a foreach()
loop to generate temporary columnar arrays. While the loop may be the microoptimized option, array_column()
gives future code readers (humans) a more comprehensible snippet.
Code: (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
Thanks mickmackusa, experimenting with your solution, I personalized it to:
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;
});
Apparently doing four separate sorts, one of them altered a previous sort, even with the !== comparison operator, but your solution of putting them together in one sort did the trick. Thanks much!!