Reputation: 193352
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>';
}
}
Upvotes: 5
Views: 1063
Reputation: 59
usort($customers, function($a, $b) {
return (int)$b->score - (int)$a->score;
});
For example your input is 14.9,14
and 14.5
and the output as 14.9,14
and 14.5
, it's treated as, 14.9=14,14.0=14
and 14.5=14
Upvotes: -1
Reputation: 9430
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.
Upvotes: 5
Reputation: 170
try
usort($customers, function($a, $b) {
return strnatcmp($b->score,$a->score);
});
Upvotes: 2