【问题标题】:usort issue with decimal numbers十进制数的排序问题
【发布时间】:2013-05-07 08:46:48
【问题描述】:

我目前正在尝试按子值对多维数组进行排序。 数组的结构是:

[0] => Array
    (
        [id] => 87
        [sold] => 50
        [stock] => 991
        [speed] => 1.5
        [days_left] => 660.66666666667
    )

[1] => Array
    (
        [id] => 97
        [sold] => 20
        [stock] => 120
        [speed] => 1.2
        [days_left] => 100
    )

[2] => Array
    (
        [id] => 36
        [sold] => 2
        [stock] => 1020
        [speed] => 1.02
        [days_left] => 1000
    )

我使用的代码是:

usort($data, function($a, $b) { return $a[$_GET['sortby']] - $b[$_GET['sortby']]; });

其中 $_GET['sortby'] 变量等于键。

到目前为止一切顺利,一切正常,除了速度之外,它对所有值进行了正确排序! 首先,我认为它与小数有关,但 days_left 也包括小数并且排序正确.. :/

正确的输出(days_left):

[0] => Array
    (
        [id] => 97
        [sold] => 20
        [stock] => 120
        [speed] => 1.2
        [days_left] => 100
    )

[1] => Array
    (
        [id] => 87
        [sold] => 50
        [stock] => 991
        [speed] => 1.5
        [days_left] => 660.66666666667
    )

[2] => Array
    (
        [id] => 36
        [sold] => 2
        [stock] => 1020
        [speed] => 1.02
        [days_left] => 1000
    )

错误的输出(速度):

[0] => Array
    (
        [id] => 97
        [sold] => 20
        [stock] => 120
        [speed] => 1.2
        [days_left] => 100
    )

[1] => Array
    (
        [id] => 87
        [sold] => 50
        [stock] => 991
        [speed] => 1.5
        [days_left] => 660.66666666667
    )

[2] => Array
    (
        [id] => 36
        [sold] => 2
        [stock] => 1020
        [speed] => 1.02
        [days_left] => 1000
    )

希望有人能帮助我!

【问题讨论】:

  • 检查你的输出..它们目前是 100% 相同的..
  • 是的,他们是,这就是问题所在!他们不应该是.. ;)

标签: php arrays sorting


【解决方案1】:

请参阅 usort 文档。浮点结果将转换为整数。为了正确工作,请使用此代码:

usort(
    $data, 
    function($a, $b) {
        $result = 0;
        if ($a[$_GET['sortby']] > $b[$_GET['sortby']]) {
            $result = 1;
        } else if ($a[$_GET['sortby']] < $b[$_GET['sortby']]) {
            $result = -1;
        }
        return $result; 
    }
);

【讨论】:

  • 无论出于何种原因,上面的代码对我来说都没有正确排序。当我在这个答案中使用代码时,确实如此。希望能帮助某人! stackoverflow.com/questions/15941137/…
【解决方案2】:

The PHP doc has a comment that has the solution to this problem. A big thanks to that guy.

这是一个用十进制数对多维数组进行排序的函数:

function usortWithFloatVals() {
    $arguments = func_get_args();
    $array = $arguments[0];
    $code = '';
    for ($c = 1; $c < count($arguments); $c += 2) {
        if (in_array($arguments[$c + 1], array("ASC", "DESC"))) {
            $code .= 'if ($a["'.$arguments[$c].'"] != $b["'.$arguments[$c].'"]) {';
            if ($arguments[$c + 1] == "ASC") {
                $code .= 'return ($a["'.$arguments[$c].'"] < $b["'.$arguments[$c].'"] ? -1 : 1); }';
            }
            else {
                $code .= 'return ($a["'.$arguments[$c].'"] < $b["'.$arguments[$c].'"] ? 1 : -1); }';
            }
        }
    }
    $code .= 'return 0;';
    $compare = create_function('$a,$b', $code);
    usort($array, $compare);
    return $array;
}

就像使用usort() 一样使用它:

usortWithFloatVals($data, function($a, $b) {
    return ($a[$_GET['sortby']] - $b[$_GET['sortby']]) ? 1 : -1;
});

【讨论】:

    【解决方案3】:

    试试strnatcmp()

    usort($output, function($a, $b) {
        return strnatcmp($b->days_left, $a->days_left);
    });
    

    【讨论】:

      【解决方案4】:

      如果有人想要更简洁的代码

      使用ceil 会将分数向上舍入并正确排序小数

      usort($data, function($a, $b) 
            {
              return ceil($a[$_GET['sortby']] - $b[$_GET['sortby']]); 
            });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        相关资源
        最近更新 更多