Reputation: 21
I have an array of strings which are consistently formatted as a letter followed by a number. I need to sort them by number first then by letter.
Sample input:
$data = [
'A1',
'A2',
'A5',
'A10',
'B2',
'B4',
'C10',
'B5',
'C1',
'B1',
'C2',
];
I need the following result:
[
'A1',
'B1',
'C1',
'A2',
'B2',
'C2',
'B4',
'A5',
'B5',
'A10',
'C10',
]
Upvotes: 0
Views: 1381
Reputation: 47900
Use array_multisort()
to sort on two rules, first remove the non-digital characters and sort by integer value, then sort normally by the leading string.
Code: (Demo)
array_multisort(preg_replace('/\D+/', '', $data), SORT_NUMERIC, $data);
Upvotes: 1
Reputation: 3812
Not the most efficient, but quite laconic approach will be to use array_multisort
and array_map
:
array_multisort(
array_map(function ($item) { return substr($item, 1); },$array),
array_map(function ($item) { return $item[0]; },$array),
$array
);
Here is working demo.
Upvotes: 0
Reputation: 212412
usort() allows you to create a custom sort rule, so you can create a rule that splits the value into letters and digits, and compare those
usort(
$data,
function($a, $b) {
sscanf($a, '%[A-Z]%d', $ac, $ar);
sscanf($b, '%[A-Z]%d', $bc, $br);
return ($ar == $br) ? $ac <=> $bc : $ar <=> $br;
}
);
Upvotes: 2