0

我有以下数组:

  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

4 回答 4

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;

施瓦茨变换旨在通过对每个元素只计算一次排序键来提高效率;Guttman-Rosler 做得更好,它还临时将排序键与完整数据(通常使用 pack,其中排序键的长度已知;这里只是使用已知的分隔符)组合在一起,这样 perl 将使用优化的构建-in 排序例程,而不是为每个比较执行 perl 代码。

于 2013-02-12T08:34:01.487 回答
2

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

use List::Util qw( maxstr );

my @sorted_anim = sort {
   maxstr(split /,/, $b) cmp maxstr(split /,/, $a)
} @anim;
于 2013-02-12T08:28:27.037 回答
2

如果您想按每个字符串中的元素计数进行排序,您的代码将执行此操作。我在 Perl 5.16 中发布的代码没有任何错误。你有旧版本的 Perl 吗?(我发现一些证据表明您的代码可能会在旧版本中产生错误)。

这是另一种选择:

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

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

于 2013-02-12T08:36:28.923 回答
0

正则表达式可以排除所有内容,或者您​​可以使用“无警告”删除警告;本地编译指示。

my $comma_re = qr!,!;   
my @animsort = sort{$b =~ s!$comma_re!!g <=> $a =~ s!$comma_re!!g} @anim;
print Dumper(\@anim,\@animsort);
于 2013-02-12T09:06:51.960 回答