This works only on the numerical part of your array, but I'm still trying to wrap my head around juggling arrays for the alphabetical sorting. Feel free to update this if anyone can add to it.
You might want to try changing your formatting if possible, because this was a headache.
$x = array(
'Regular 1 000',
'Regular 500',
'Regular 2 000',
'Big',
'Regular 1 000 000',
'Regular 50 000'
);
Gives:
EDIT: Eureka!
$x = array(
'A 100', // extra for testing
'Regular 1 000',
'Regular 500',
'Regular 2 000',
'Big',
'Regular 1 000 000',
'Regular 50 000'
);
function cus_sort($a, $b) { // you can also just do $x = function ($a, $b) {}
$tmp_a = array(); $tmp_b = array(); // temp storage
$tmp_a = explode(" ", $a, 2);
if (@$tmp_a[1]) { // tmp_a exists (suppress invalid offset error if not)
$a_numeric = (int)preg_replace("/[^0-9]/", '', $tmp_a[1]);
// remove all non-numerical (...should add hyphens if needed...)
} else {
$a_numeric = false; // text only.
}
// else make sure that it evaluates false when we check.
$tmp_b = explode(" ", $b, 2); // split into maximum 2 parts at first space.
if (@$tmp_b[1]) { // tmp_b exists (suppress invalid offset error if not)
$b_numeric = (int)preg_replace("/[^0-9]/", '', $tmp_b[1]);
} else {
$b_numeric = false;
}
// onwards to sorting
if ($tmp_a[0] == $tmp_b[0]) { //alphabetical parts are the same.
// numerical sort
if (($a_numeric > $b_numeric) || (!$b_numeric)) {
return 1;
} elseif (($a_numeric < $b_numeric) || (!$a_numeric)) {
return -1;
} else {
return 0;
}
} else {
// alpha sort
$compare = strcasecmp($tmp_a[0], $tmp_b[0]);
// see note below
if ($compare > 0) {
return 1;
} elseif ($compare < 0) {
return -1;
} else {
return 0;
}
}
}
uasort($x, "cus_sort");
Note: strcasecmp(string $a, string $b)
is a case insensitive numerical way to check if in order.
print_r
returns:
Array
(
[0] => A 100
[4] => Big
[2] => Regular 500
[1] => Regular 1 000
[3] => Regular 2 000
[6] => Regular 50 000
[5] => Regular 1 000 000
)