I am trying to sort a multidimensional array by its keys with exceptions to the sort. I know that I can use array_multisort(array_column ...
to sort by multiple columns but my issue is that my sort is more by type than it is by alphanumeric or numerical.
An example of the multidimensional array that I am working with is below:
[
0 ['woid'=>17642-1,'schedule'=>'URGENT']
1 ['woid'=>17643-1,'schedule'=>'ASAP']
2 ['woid'=>17643-2,'schedule'=>'ASAP']
3 ['woid'=>17644-1,'schedule'=>'JAN']
4 ['woid'=>NC323-1,'schedule'=>'URGENT']
5 ['woid'=>NC324-1,'schedule'=>'ASAP']
]
What I want is to have this sorted by key=woid
starting with 'NC' at the top sorted ASC, then sort the remaining by key=schedule
with the following order:
URGENT
JAN
FEB
MAR
APR
MAY
JUN
JUL
AUG
SEP
OCT
NOV
DEC
ASAP
all while retaining an ASC sort on the key=woid
I understand this may be confusing. Below is an example of the desired outcome with the array example above:
[
0 ['woid'=>NC323-1,'schedule'=>'URGENT']
1 ['woid'=>NC324-1,'schedule'=>'ASAP']
2 ['woid'=>17642-1,'schedule'=>'URGENT']
3 ['woid'=>17644-1,'schedule'=>'JAN']
4 ['woid'=>17643-1,'schedule'=>'ASAP']
5 ['woid'=>17643-2,'schedule'=>'ASAP']
]
If more information is needed or a larger example I am more than happy to take the time and provide it.
You'll need to use usort
for multiple sort criteria like this.
For your usort
comparison function, after you've figured out whether each woid
starts with 'NC', you can compare the results of that check mathematically, then use the order from your custom sort array, and finally use strcmp
to break ties.
$order = ['URGENT','JAN','FEB','MAR','APR','MAY','JUN',
'JUL','AUG','SEP','OCT','NOV','DEC','ASAP'];
$order = array_flip($order);
usort($array, function($a, $b) use ($order) {
$aNC = strpos($a['woid'], 'NC') === 0;
$bNC = strpos($b['woid'], 'NC') === 0;
return ($bNC - $aNC)
?: ($order[$a['schedule']] - $order[$b['schedule']])
?: strcmp($a['woid'], $b['woid']);
});
In the first comparison, $aNC
and $bNC
will be booleans, but will be converted to ints (0 or 1) for the subtraction. If that comparison returns 0 (meaning both or neither woid
value starts with 'NC'), the second comparison will be evaluated.
In the second comparison, the position of the two schedule
values in the $order
array is subtracted. If that comparison returns 0, (meaning both schedule
values are the same), the third comparison will be evaluated.
In the third comparison, strcmp
is used to return <0, 0, or >0 depending on the string comparison of the two woid
values.