usort 函数结果错误

usort function result is wrong

今天我提供了这个问题的答案,我写了一个脚本,但是我发现出了问题。

这是第一个脚本

<?php 
$array = array( 
            "0" => array (
               "id" => 1204,
               "custom_price" => 33.1500    
            ),
            
            "1" => array (
               "id" => 1199,
               "custom_price" => 15.83  
            ),
            
            "2" => array (
               "id" => 1176,
               "custom_price" => 16.83  
            )
         );

usort($array, function($a, $b) {
    return $a['custom_price'] - $b['custom_price'];
});
echo "<pre>";
print_r($array);

它的输出是(你也可以检查output on sandbox

<pre>Array
(
    [0] => Array
        (
            [id] => 1176
            [custom_price] => 16.83
        )

    [1] => Array
        (
            [id] => 1199
            [custom_price] => 15.83
        )

    [2] => Array
        (
            [id] => 1204
            [custom_price] => 33.15
        )

)

所以,我想要的输出应该类似于 (custom_price 15.83, 16.83, 33.15000),但实际输出是 (custom_price 16.83,15.83,33.15000)。你可以看到 15.83 是 16.83 中最小的。排序结果错误

因此,当我将 custom_price 15.83 更改为 14.83 时,排序输出是正确的

<pre>Array
(
    [0] => Array
        (
            [id] => 1199
            [custom_price] => 14.83
        )

    [1] => Array
        (
            [id] => 1176
            [custom_price] => 16.83
        )

    [2] => Array
        (
            [id] => 1204
            [custom_price] => 33.15
        )

)

you can see output on sandbox

我不明白这是怎么回事..对此有什么想法吗?

我的问题是: 我检查了每次迭代但无法确定问题所在。当 custom_price 是 15.83 那么结果是错误的。为什么?

更新函数

usort($array, function($a, $b) {
    return $a['custom_price'] > $b['custom_price'];
});

关于usortPHP manual中有一个完整的例子。这是解决您问题的修改版本:

<?php
function cmp($a, $b)
{
    if ($a['custom_price'] == $b['custom_price']) {
        return 0;
    }
    return ($a['custom_price'] < $b['custom_price']) ? -1 : 1;
}

下面的代码可以解决您的问题,

usort($array, function($a, $b) {
    if($a['custom_price']==$b['custom_price']) return 0;
    return $a['custom_price'] > $b['custom_price'] ? 1 : -1;
});

PHP 手册中有关于 usort() 比较函数(在 http://php.net/manual/en/function.usort.php#refsect1-function.usort-parameters)的 return 值的警告...

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.

同样来自PHP 7. 你可以使用飞船操作符<=> which returns 1, 0, -1 取决于两个值的比较...

usort($array, function($a, $b) {
    return $a['custom_price'] <=> $b['custom_price'];
});

echo "<pre>";
print_r($array);