Perl内联数组排序(如何避免'隐式拆分'错误)

时间:2013-02-12 08:16:09

标签: perl unix sorting

我有以下数组:

  my @anim = ('rn4,mm8,bosTau2,canFam2,dasNov1,echTel1',
  'rn4,mm8,oryCun1,bosTau2,canFam2,dasNov1,echTel1');

它包含多个字符串,每个字符串都以逗号分隔。 我想要做的是根据字符串中最伟大的成员对它们进行排序。 因此,我试图做的是:

my @animsort = sort{scalar(split(",",$b)) <=> scalar(split(",",$a))} @anim;

但它给出了这个错误:

Use of implicit split to @_ is deprecated at ./scripts/mycode.pl line 35

这样做的正确方法是什么?

4 个答案:

答案 0 :(得分:6)

如果“最大成员”表示最后一个成员,请使用列表切片:

my @sorted_anim = sort {
    (split /,/, $b)[-1] cmp (split /,/, $a)[-1]
} @anim;

使用Schwartzian变换:

my @sorted_anim = map $_->[0],
    sort { $b->[1] cmp $a->[1] }
    map [ $_, (split /,/, $_)[-1] ],
    @anim;

或Guttman-Rosler变换:

my @sorted_anim = map /,(.*)/s,
    sort { $b cmp $a }
    map { (split /,/, $_)[-1] . ",$_" }
    @anim;

Schwartzian变换旨在通过仅为每个元素计算一次排序键来提高效率; Guttman-Rosler还通过临时组合排序键和完整数据(通常使用pack,其中排序键具有已知长度;这里只有一个已知的分隔符)以便perl将使用优化的内置而更好-in sort例程,而不是为每次比较执行perl代码。

答案 1 :(得分:2)

scalar()不会返回“字符串中最大的成员”或导致split这样做。也许您正在寻找List::Utilmaxstr

use List::Util qw( maxstr );

my @sorted_anim = sort {
   maxstr(split /,/, $b) cmp maxstr(split /,/, $a)
} @anim;

答案 2 :(得分:2)

如果要按每个字符串中的元素数排序,您的代码就会这样做。我在Perl 5.16中发布的代码没有任何错误。你有旧版本的Perl吗? (我发现some evidence您的代码可能会在旧版本中生成错误。

这是另一种选择:

my @animsort = sort{(() = $b =~ /,/g) <=> (() = $a =~ /,/g)} @anim;

这可以通过计算逗号来排序,而不是实际拆分字符串。有趣的() =语法是为了确保正则表达式被视为在列表上下文中,因此我们可以计算匹配。

答案 3 :(得分:0)

Regexp可能是唯一的,或者您可以通过“无警告”删除警告; pragma本地。

my $comma_re = qr!,!;   
my @animsort = sort{$b =~ s!$comma_re!!g <=> $a =~ s!$comma_re!!g} @anim;
print Dumper(\@anim,\@animsort);