我有一个1,660行数组:
...
H00504
H00085
H00181
H00500
H00103
H00007
H00890
H08793
H94316
H00217
...
领导人物永远不会改变。它总是“H”然后是五位数。但是,当我在Perl中做我认为是数字排序时,我会得到奇怪的结果。某些段按顺序排序,但随后会启动另一个段。以下是排序后的细分:
...
H01578
H01579
H01580
H01581
H01582
H01583
H01584
H00536
H00537
H00538
H01585
H01586
H01587
H01588
H01589
H01590
...
我正在尝试的是:
my @sorted_array = sort {$a <=> $b} @raw_array;
但显然它不起作用。谁知道为什么?
我应该补充一点,虽然这些值都有“H”前置,但未来我们可能会在其他字母前加上额外的数据。这意味着删除H,排序,然后替换H,不是解决方案
答案 0 :(得分:9)
如果你正在使用use strict; use warnings;
,你可能会遇到很多形式的错误
Argument "H01578" isn't numeric in numeric comparison (<=>)
您的所有元素都不是数字,因此它们都被视为零。这就是Perl认为您当前代码的结果已经排序的原因。
如果您希望按字母排序,则按数字排序(这与按数字排序相同,因为所有字母都相同):
my @sorted_array = sort @raw_array;
是
的缩写my @sorted_array = sort { $a cmp $b } @raw_array;
如果您想按编号排序而不考虑前导字母,请改为使用以下内容:
my @sorted_array =
sort { substr($a, 1) <=> substr($b, 1) }
@raw_array;
答案 1 :(得分:5)
如果您希望按初始字符排序为主键,后跟数字作为辅助键,则可以使用Schwartzian Transform的变体,在排序之前从所有数据中提取两个字段进行比较。 / p>
该程序演示
use strict;
use warnings;
my @data = <DATA>;
chomp @data;
my @sorted = sort map $_->[0],
sort { $a->[1] cmp $b->[1] or $a->[2] <=> $b->[2] }
map [$_, /(.)(.+)/], @data;
print "$_\n" for @sorted;
__DATA__
A1180
B0802
B1284
C0899
C1455
C0765
A1207
A0909
C0921
C1060
A1067
B1486
A1268
B0772
C0595
B0734
A1004
A0607
A1323
B1181
<强>输出强>
A0607
A0909
A1004
A1067
A1180
A1207
A1268
A1323
B0734
B0772
B0802
B1181
B1284
B1486
C0595
C0765
C0899
C0921
C1060
C1455
工具已成功完成
您可能更喜欢使用不使用Transform的替代方法。该程序具有相同的输出,但对于大型数据集而言运行速度要慢得多
my @sorted = sort {
my @a = $a =~ /(.)(.+)/;
my @b = $b =~ /(.)(.+)/;
$a[0] cmp $b[0] or $a[1] <=> $b[1];
} @data;
答案 2 :(得分:3)
要忽略任何不是数字的内容,您还可以:
use strict;
use warnings;
my @sorted = sort {
(my $x = $a) =~ s/\D//g;
(my $y = $b) =~ s/\D//g;
($x?$x:0) <=> ($y?$y:0)
} <DATA>;
print "$_" for @sorted;
__DATA__
a123
a/9999/gyu
b2
333
bbb
c888hh
0
结果:
bbb
0
b2
a123
333
c888hh
a/9999/gyu
答案 3 :(得分:1)
你想要这样的东西:
my @sorted_array = sort {substr($a, 1) <=> substr($b,1)} @raw_array;
有关示例,请参阅:http://ideone.com/trnfy。
如果您使用标准排序,而不使用{...}
,则该标准排序也可以正常运行。您当前的代码可能会失败,因为所有比较都返回0,因为您正在对字母数字数据进行数字比较。
答案 4 :(得分:1)
您可以使用List::UtilsBy::sort_by
:
use List::UtilsBy qw( sort_by );
my @sorted_array = sort_by { substr($_, 1) } @raw_array;