【问题标题】:Natural array sorting with proper decimal support in PHP在 PHP 中具有适当小数支持的自然数组排序
【发布时间】:2021-06-23 14:53:16
【问题描述】:

我想用自然顺序的数字对数组进行排序,因此具有较大值的数字排在较小的后面,如下所示:

php > $numbers = array('10 Apple', '2 Grapes', '3 Apples', '3.2 Apples', '3.1 Apples', '3.3 Apples', '3.10 Apples', '3.11 Apples', 'Lots of Apples');
php > natsort($numbers);

这是我得到的结果,这不是我需要的结果,小数没有正确受到威胁。

php > print_r($numbers);
Array
(
    [1] => 2 Grapes
    [2] => 3 Apples
    [4] => 3.1 Apples
    [3] => 3.2 Apples
    [5] => 3.3 Apples
    [6] => 3.10 Apples
    [7] => 3.11 Apples
    [0] => 10 Apple
    [8] => Lots of Apples
)

已经有一个类似的问题Array Sorting in php for decimal values,但没有找到合适的答案。

属性排序的预期输出是

Array
(
    [1] => 2 Grapes
    [2] => 3 Apples
    [4] => 3.1 Apples
    [6] => 3.10 Apples
    [7] => 3.11 Apples
    [3] => 3.2 Apples
    [5] => 3.3 Apples
    [0] => 10 Apple
    [8] => Lots of Apples
)

所以我有点期待natsort() 做到这一点,但它看起来有问题,我必须自己实现类似的逻辑?对吗?

我正在考虑的一个解决方案是以某种方式将数字重新格式化为固定精度,并希望 natsort() 那时可以工作,但我想知道是否有更简单的解决方案或 PHP 内置的解决方案。

我试过https://github.com/awssat/numbered-string-order,这很有趣,但也不支持小数。

【问题讨论】:

  • usort()与比较函数一起使用,从字符串中提取数字并进行比较。
  • 如果所有字符串都以Apples 结尾,为什么不直接删除它并按数字排序?
  • StackOverflow 不是免费的编码服务。你应该try to solve the problem first。请更新您的问题以在minimal reproducible example 中显示您已经尝试过的内容。如需更多信息,请参阅How to Ask,并拨打tour :)
  • 谢谢大家,我稍微改进了一下问题

标签: php arrays sorting


【解决方案1】:

我不能 100% 确定您的规范,所以请对此进行测试,但 strnatcmp 似乎可以用于在 usort 中运行 natsort 变体。如果传递给比较器的两个字符串都以浮点数开头,则将它们转换为浮点数并使用飞船,否则,默认为strnatcmp

<?php

$numbers = ['10 Apple', '2 Grapes', '3 Apples', '3.2 Apples', '3.1 Apples', '3.3 Apples', '3.10 Apples', '3.11 Apples', 'Lots of Apples'];

usort($numbers, function ($a, $b) {
    if (preg_match("~^\d*\.\d+\b~", $a, $m)) {
        $aa = (float)$m[0];

        if (preg_match("~^\d*\.\d+\b~", $b, $m)) {
            $bb = (float)$m[0];
            return $aa <=> $bb;
        }
    }

    return strnatcmp($a, $b);
});
print_r($numbers);

【讨论】:

    猜你喜欢
    • 2019-12-12
    • 2010-10-24
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多