Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can this usort() function not properly sort decimals?

Tags:

php

usort

Why are decimals not properly sorted:

13
11
14
10
12.5
---------------------------------------------------------
descending order:
14
12.5
13
11
10

with this code:

class Customer {
    public $score;
    public function __construct($score) {
        $this->score = $score;
    }
}

$customers = [];
$customers[] = new Customer(13);
$customers[] = new Customer(11);
$customers[] = new Customer(14);
$customers[] = new Customer(10);
$customers[] = new Customer(12.5);

if(is_array($customers) && count($customers) > 0)
{
    foreach($customers as $customer)
    {
        echo '<div>'.$customer->score.'</div>';
    }
}

echo '<hr/>';
echo '<div>descending order:</div>';
usort($customers, function($a, $b) {
    return $b->score - $a->score;
});


if(is_array($customers) && count($customers) > 0)
{
    foreach($customers as $customer)
    {
        echo '<div>'.$customer->score.'</div>';
    }
}
like image 399
Edward Tanguay Avatar asked Jan 14 '16 15:01

Edward Tanguay


2 Answers

Casting decimal 0.5 to integer changes it to 0. Change your usort function to:

usort($customers, function($a, $b) {
    if($b->score - $a->score >= 0){
        return 1;
    }
    return -1;
});

Output:

descending order:
14
13
12.5
11
10

PHP Manual says:

Caution: Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.

like image 127
n-dru Avatar answered Oct 03 '22 09:10

n-dru


try

usort($customers, function($a, $b) {
    return strnatcmp($b->score,$a->score);
});
like image 28
4 revs, 2 users 66% Avatar answered Oct 03 '22 10:10

4 revs, 2 users 66%