我需要对数字进行排序,但我无法按照我想要的方式进行操作。
示例输入:
15.12
16.1
15.2
15.1
预期产出:
15.1
15.2
15.12
16.1
我尝试了正常的排序,也为此Sort::Naturally
。两者都没有给我预期的输出。
我也知道我可以按照以下方式进行排序,以我想要的方式对其进行排序。
my @sorted =
map sprintf('%vd', $_),
sort
map join('', map chr, split /\./),
@data;
我想知道是否有一些我可以使用的预先存在的模块。
提前致谢。
答案 0 :(得分:6)
如果我理解正确,您希望先按整数值对数字进行排序,然后将小数部分视为整数本身,因此.12
大于.2
,如示例所示(12 > 2)。
我认为最自我解释的方法是使用自定义排序,按照你所说的分割它们之后:
@sorted = sort {
my ($a1, $a2) = split /\./, $a;
my ($b1, $b2) = split /\./, $b;
$a1 <=> $b1 or $a2 <=> $b2
} @numbers;
答案 1 :(得分:3)
您需要将(<=>
)数字与特殊$a
和$b
变量进行比较。请注意,您可以使用<=>
替换cmp
来对字符串执行相同操作。
use warnings;
use strict;
my @nums = qw(15.1 16.1 15.12);
@nums = sort {$a <=> $b} @nums;
print "$_\n" for @nums;
__END__
15.1
15.12
16.1
答案 2 :(得分:3)
您似乎正在尝试对版本号进行排序,其中每个组件都是独立排序的。排序::自然不会起作用,因为它忽略了非字母数字字符,但还有其他几个模块可以做到这一点。
Sort::Versions将其输入分为句点或连字符,并按字母顺序或数字顺序对每个组进行排序,具体取决于是否存在非数字字符:
use strict;
use warnings 'all';
use 5.010;
use Sort::Versions;
my @versions = (
15.12,
16.1,
15.2,
15.1
);
say for sort { versioncmp($a, $b) } @versions;
输出:
15.1
15.2
15.12
16.1
Sort :: Versions期望输入匹配某些常见的版本字符串格式;如果您需要对不同的格式进行排序,请检查文档中的规则以确保它适合您。
Sort::Key::Natural更灵活,因为它会分割所有单词边界,而不仅仅是句点和连字符,但在这种情况下它的作用相同:
use strict;
use warnings 'all';
use 5.010;
use Sort::Key::Natural qw(natsort);
my @versions = (
15.12,
16.1,
15.2,
15.1
);
say for natsort @versions;
(输出与Sort :: Versions相同)
Sort :: Key :: Natural有一些很好的附加功能,比如能够就地排序和自定义排序顺序。它在我的基准测试中也明显快于Sort :: Versions,尽管只有在你对大型数组进行排序时才会这么做。
答案 3 :(得分:1)
关于@stevieb 提供的答案,值“15.2”没有被删除:它在原始数组中丢失了。不过,运算符 <=>
和 cmp
不可互换。它们分别用于比较数字和字符串。