在Perl中查找满足特定条件的数组项?

4

如果存在符合特定条件的数组项,是否有一种Perl惯用语来查找该项?

my $match = 0;
foreach(@list){
   if (match_test($_)){
      $result = $_;
      $match = 1;
      last;
      }
   }
$match || die("No match.");
say $result, " is a match.";

这个例子看起来有点别扭。我希望Perl能够有更干净的处理方式。

2个回答

14

是的,grep 就是你要找的:

my @results = grep {match_test($_)} @list;

grep返回@listmatch_test为真的子集。在大多数其他函数语言中,grep被称为filter

如果您只想要第一个匹配项,请使用List::Util中的first函数。

use List::Util qw/first/;

if (my $result = first {match_test($_)} @list) {
    # use $result for something
} else {
    die "no match\n";
}

6
$scalar@array 中时,表达式 @array ~~ $scalar 为真。 - daxim
1
@daxim => 假设您使用的是足够新的 Perl 版本以支持智能匹配(5.10+) - Eric Strom
@C.W.Holeman II:我在我的回答中给出了这两种情况的示例。 - Ether
3
从 Perl 5.10.1 开始,~~ 运算符的顺序很重要。因此,它应该为 $scalar ~~ @array。请注意,为了帮助理解,将 ~~ 看作 "in" 的同义词。 - draegtun

6
如果存在多个匹配项:
 my @matches = grep { match_test($_) } @list;

如果只有一个匹配项,List::Util 的 'first' 更快(假设找到了匹配项):

 use List::Util 'first';
 if (my $match = first { match_test($_)} @list)
 {
      # do something with the match...
 }

在非常大的数组上速度更快,但这并不是常见情况。 - ysth
如果没有任何结果,它也不会更快,因为仍然需要检查每个元素。 - Ether

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接