I have a multidimensional array in this structure:
$arr = [
0 => ['ref' => 'Q1'],
1 => ['ref' => 'C6'],
2 => ['ref' => 'C13'],
3 => ['ref' => 'S3'],
4 => ['ref' => 'Q11'],
8 => ['ref' => 'S7'],
9 => ['ref' => 'C4'],
];
I want to sort the array so that the order of values are S, Q, D, C, P, E and if possible have each alphanumeric ascending while also keeping the associate key [ref], like this:
$arr = [
0 => ['ref' => 'S3'],
1 => ['ref' => 'S7'],
2 => ['ref' => 'Q1'],
3 => ['ref' => 'Q11'],
4 => ['ref' => 'C4'],
8 => ['ref' => 'C6'],
9 => ['ref' => 'C13'],
];
This code should do what you want. It uses usort
with a compare function that first looks at the leading character and sorts that based on your specified order: S, Q, D, C, P, E. If the character is the same, it then compares the integer part of the value. Now the problem is that this loses the keys. We can't use uasort
to get around that, as it will move the keys with the corresponding value. To get around that we first grab the keys of the array, then combine the keys with the sorted array at the end:
function mysort($a, $b) {
$sort_order = ['S', 'Q', 'D', 'C', 'P', 'E'];
// first, sort by leading character
$s = array_search($a['ref'][0], $sort_order) - array_search($b['ref'][0], $sort_order);
if ($s != 0) return $s;
// if the same, sort by numeric part
return (int)substr($a['ref'], 1) - (int)substr($b['ref'], 1);
}
$keys = array_keys($arr);
usort($arr, 'mysort');
$arr = array_combine($keys, $arr);
Output:
Array
(
[0] => Array
(
[ref] => S3
)
[1] => Array
(
[ref] => S7
)
[2] => Array
(
[ref] => Q1
)
[3] => Array
(
[ref] => Q11
)
[4] => Array
(
[ref] => C4
)
[8] => Array
(
[ref] => C6
)
[9] => Array
(
[ref] => C13
)
)