'Sort flat array by multiple rules

I would like some help regarding my sort function for an array as it is not working as I expected.

This function is to sort array of [0,1,2,3,4,...23] into array [9,10,11,12,...,23,0,1,2,3,4,5,6,7,8], I was planning on integrating this function to sort data in my matrix table.

I cant figure out why the values [0,1,2] are out of place.

Here is the code:

<?php
function cmp($a, $b)
{
    if ($a == $b) return 0;
    if ($a == 9) return -1;
    if ($b == 9) return 1;
    return strcmp($a, $b);
}
$a = array(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23);
echo'<br>';
usort($a, "cmp");

//print_r($a);
echo '<pre>';
    print_r($a);
echo '</pre>';

$arrlength=count($a);
for($x=0;$x<$arrlength;$x++)
{
    echo $a[$x];
    echo "<br>";
}
?>


Solution 1:[1]

It appears you'd like to sort integers by number of digits in reverse, then sequentially within each digit count group. Also, there is a special constraint that 9 counts as a double-digit number.

This function generates the expected output but may require modifications to handle conditions not obvious from your test case, such as numbers 90 and over (but from the comments, this relates to time, so it's probably sufficient):

function cmp($a, $b) {

  // Handle nines
  if ($a == 9) { return -1; }
  if ($b == 9) { return 1;  }

  // Perform a comparison by digit count
  $cmp = strcmp(strlen($a), strlen($b));

  if ($cmp === 0) { // Same digit count, sort sequentially
    return $a - $b; 
  }

  return -$cmp; // Different digit counts; sort in reverse
}

Solution 2:[2]

Use 3-way comparisons as needed and fallback to the next sorting criteria when there is a tie.

  1. Sort by "if 9" (false comes before true when sorting ASC)
  2. Then sort by string length DESC
  3. Then sort by value ASC

Code: (Demo)

usort(
    $array,
    fn($a, $b) =>
        ($a !== 9) <=> ($b !== 9)
        ?: strlen($b) <=> strlen($a)
        ?: $a <=> $b
 );

var_export($array);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ggorlen
Solution 2 mickmackusa