当条目的某些部分包含字符时,Perl对数组进行数字排序
可能重复:当条目的某些部分包含字符时,Perl对数组进行数字排序,perl,sorting,Perl,Sorting,可能重复: 我有一个如下所示的数组: my @arr = qw(r1.1 r10.1 r2.1 r33.1); 如何在Perl中对它们进行排序,以便生成: $VAR = ['r1.1', 'r2.1', 'r10.1', 'r33.1']; 下面是一个可以工作的排序子程序: sub mySort { $a =~ /^r(\d+).(\d+)$/; my ($a1, $a2) = ($1, $2); $b =~ /^r(\d+).(\d+
我有一个如下所示的数组:
my @arr = qw(r1.1 r10.1 r2.1 r33.1);
如何在Perl中对它们进行排序,以便生成:
$VAR = ['r1.1', 'r2.1', 'r10.1', 'r33.1'];
下面是一个可以工作的排序子程序:
sub mySort {
$a =~ /^r(\d+).(\d+)$/;
my ($a1, $a2) = ($1, $2);
$b =~ /^r(\d+).(\d+)$/;
my ($b1, $b2) = ($1, $2);
return $a2 <=> $b2 if ($a1 == $b1);
return $a1 <=> $b1;
}
您可以使用:
例如,这将正确地排序qw(r1.2 r1.1)。我认为你们的元素就像是版本号(“r”让我想到了“修订版”),所以1.10不同于(大于)1.1。如果它们只是实数,这可以做得更简单。对于一个小数据集,这是可以的,但这不是一个很好的解决方案-请参阅上面链接的可能的重复。主要问题是,对于排序中执行的每个比较,
a
和b
都需要正则表达式-对于一个长列表,这可能是多次。“double return”令人困惑,一点也不惯用:编写return$a1$b1或$a2$b2这样的代码更为正常
在这种情况下,如果$a1==$b1
则第一次比较的值为零,因此对下一次比较进行求值。@martin clayton,返回$a1$b1或$a2$b2代码>表示(返回$a1$b1)或($a2$b2)代码>。使用|
或parens.@martin clayton,双匹配比使用Schwartzian变换消除双匹配要快。@sjs,$a=~/^r(\d+)(\d+)$/;我的($a1,$a2)=($1,$2)
是一种相当糟糕的方式,或者写my($a1,$a2)=$a=~/^r(\d+)(\d+)$/
映射“r$”,排序{$a$b}映射{substr$\U1}@arr
my @sorted = sort mySort @arr;
my @sorted =
sort {
my @a = $a =~ /([0-9]+)/g;
my @b = $b =~ /([0-9]+)/g;
return $a[0] <=> $b[0] || $a[1] <=> $b[1];
}
@arr;
my @sorted =
map substr($_, 8),
sort
map pack('NNa*', /([0-9]+)\.([0-9]+)/, $_),
@arr;
use Sort::Key::Natural qw(natsort);
my @arr = qw(r1.1 r10.1 r2.1 r33.1);
my @sorted = natsort @arr;