While a larger set of units may need to work in conjunction with a lookup map of values relating to different unit abbreviations, this question is only dealing with GB
and TB
which will simply sort alphabetically.
For best efficiency, perform a single loop over the input values and parse the leading number and its trailing unit expression. The remainder of the strings appear to be irrelevant to accurate sorting.
Now that you have flat arrays to sort with, pass the units then the numbers into array_multisort()
, then write the original array as the third parameter so that it is the "affected" array.
See also this related answer to a very similar question: PHP: Sort an array of bytes
Code: (Demo)
$nums = [];
$units = [];
foreach ($array as $v) {
[$nums[], $units[]] = sscanf($v, '%d%[A-Z]');
}
array_multisort($units, $nums, $array);
var_export($array);
If the input is:
$array = [
'a' => '1GB - 4GB',
'b' => '1TB - 2TB',
'c' => '3TB - 5TB',
'd' => '5GB - 16GB',
'e' => '6TB+',
'f' => '17GB - 32GB',
'g' => '33GB - 63GB',
'h' => '64GB - 120GB',
'i' => '121GB - 200GB',
'j' => '201GB - 300GB',
'k' => '301GB - 500GB',
'l' => '501GB - 1TB',
];
The output is:
array (
'a' => '1GB - 4GB',
'd' => '5GB - 16GB',
'f' => '17GB - 32GB',
'g' => '33GB - 63GB',
'h' => '64GB - 120GB',
'i' => '121GB - 200GB',
'j' => '201GB - 300GB',
'k' => '301GB - 500GB',
'l' => '501GB - 1TB',
'b' => '1TB - 2TB',
'c' => '3TB - 5TB',
'e' => '6TB+',
)