当条目的某些部分包含字符时,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;