josh josh - 6 months ago 19
PHP Question

Using usort() on multidimensional alphanumeric array (numbers first)

Here is an example array I am attempting to sort:

$array = (object)array(

'this' => 'that',
'posts'=> array(
'title' => '001 Chair',
'title' => 'AC43 Table',
'title' => '0440 Recliner',
'title' => 'B419',
'title' => 'C10 Chair',
'title' => '320 Bed',
'title' => '0114'
),
'that' => 'this'
);

usort($array->posts, 'my_post_sort');


Here is the function I am using to sort:

function my_post_sort($a, $b) {

$akey = $a->title;
if (preg_match('/^[0-9]*$',$akey,$matches)) {
$akey = sprintf('%010d ',$matches[0]) . $akey;
}
$bkey = $b->title;
if (preg_match('/^[0-9]*$',$bkey,$matches)) {
$bkey = sprintf('%010d ',$matches[0]) . $bkey;
}

if ($akey == $bkey) {
return 0;
}

return ($akey > $bkey) ? -1 : 1;
}


This gives me the following results:

'posts', array(
'title' => 'C10 Chair',
'title' => 'B419',
'title' => 'AC43 Table',
'title' => '320 Bed',
'title' => '0440 Recliner',
'title' => '0114',
'title' => '001 Chair'
)


Now, the last step I need is getting the numbers to appear (descending) before the letters (descending).

Here is my desired output:

'posts', array(
'title' => '320 Bed',
'title' => '0440 Recliner',
'title' => '0114',
'title' => '001 Chair',
'title' => 'C10 Chair',
'title' => 'B419',
'title' => 'AC43'
)


I've tried all kinds of sorts, uasorts, preg_match, and other functions; and just cannot seem to figure out the last step.

Any suggestions or assistance? Thank you.

Answer

Try this comparing function:

function my_post_sort($a, $b) {

    $akey = $a->title;
    $bkey = $b->title;

    $diga = preg_match("/^[0-9]/", $akey);
    $digb = preg_match("/^[0-9]/", $bkey);

    if($diga && !$digb) {
        return -1;
    }

    if(!$diga && $digb) {
        return 1;
    }

    return -strcmp($akey, $bkey);
}

It will sort in descending order, but place digits before other symbols.