Search code examples
phpalgorithmsortingphp-7.4

PHP asort by value ASC, value 0 should go last


I have the following array:

$values = [
  'a' => 0,
  'b' => 1,
  'c' => 0,
  'd' => 3,
  'e' => 2
];

I need to be able to sort it like so:

$values = [
  'b' => 1,
  'e' => 2,
  'd' => 3,
  'a' => 0,
  'c' => 0
];

The fastest solution I managed to come up with is:

$zero = array_filter($values, fn($val) => $val === 0);

$non_zero = array_diff_assoc($values, $zero);
asort($non_zero);

$result = array_merge($non_zero, $zero);

Sorting rules:

  • keys need to be preserved
  • key order does not matter for the same value

My question is: is there a better way to do this?

Here is a sandbox version

Thank you!

UPDATE

It looks like this one might work too:

asort($values);
uasort($values, function($a, $b){
    return $a === 0 ? 1 : -1;
});

Sandbox for this version

Any better ideas?


Solution

  • I managed to come up with this solution which looks decent:

    $values = [
      'i' => 2,
      'a' => 0,
      'b' => 1,
      'f' => 1,
      'c' => 0,
      'd' => 3,
      'g' => 3,
      'e' => 2,
      'h' => 3,
    ];
    
    uasort($values, function($a, $b){
        if ($a === 0) {
            return 1;
        }
        
        if ($b === 0 || $a === $b) {
            return 0;
        }
        
        return $a < $b && $b !== 0 ? -1 : 1;
    });
    

    And it appears to be returning the expected output on all cases:

    Array
    (
        [b] => 1
        [f] => 1
        [i] => 2
        [e] => 2
        [d] => 3
        [g] => 3
        [h] => 3
        [c] => 0
        [a] => 0
    )