Perl:测试值是否在数组中的好方法?

时间:2010-12-31 14:41:02

标签: arrays perl

如果我有一个数组:

@int_array = (7,101,80,22,42);

如何在不循环遍历每个元素的情况下检查整数值80是否在数组中?

5 个答案:

答案 0 :(得分:31)

你不能没有循环。这是数组意义的一部分。您可以使用grep或smartmatch使用隐式循环,但仍然存在循环。如果你想避免循环,请改为使用哈希(或者另外)。

# grep
if ( grep $_ == 80, @int_array ) ...

# smartmatch
use 5.010001;
if ( 80 ~~ @int_array ) ...

在使用smartmatch之前,请注意:

http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#The_smartmatch_family_of_features_are_now_experimental

  

smartmatch系列功能现已具有实验性

     

智能匹配,在v5.10.0中添加并在v5.10.1中进行了重大修订,一直是一个常规投诉点。尽管有许多方法可用,但它也证明了Perl的用户和实现者都存在问题和困惑。关于如何最好地解决问题,已经提出了许多建议。很明显,smartmatch几乎肯定会在将来改变或消失。不建议依赖其当前行为。

     

现在,当解析器看到〜,给定或何时发出警告。要禁用这些警告,可以将此行添加到适当的范围

答案 1 :(得分:7)

CPAN解决方案:使用List::MoreUtils

use List::MoreUtils qw{any}; 
print "found!\n" if any { $_ == 7 } (7,101,80,22,42);

如果你需要在同一个数组中进行多次查找,一种更有效的方法是将数组存储在哈希中一次并查找哈希:

@int_array{@int_array} = 1;
foreach my $lookup_value (@lookup_values) {
    print "found $lookup_value\n" if exists $int_array{$lookup_value}
}

为什么要使用此解决方案而不是替代方案?

  • 在5.10之前无法在Perl中使用智能匹配。根据brian d foy] 2的SO帖子,智能匹配是短路的,因此它与5.10的“任何”解决方案一样好。

  • grep解决方案循环遍历整个列表,即使1,000,000长列表的第一个元素匹配也是如此。 any会在找到第一个匹配时短路并退出,因此效率更高。原始海报明确表示“没有遍历每个元素”

  • 如果您需要进行大量的查找,哈希创建的一次性沉没成本使得哈希查找方法比其他方法更有效。请参阅this SO post for details

答案 2 :(得分:3)

另一种检查数组中数字的方法:

#!/usr/bin/env perl

use strict;
use warnings;

use List::Util 'first';

my @int_array       = qw( 7 101 80 22 42 );
my $number_to_check = 80;

if ( first { $_ == $number_to_check } @int_array ) {
    print "$number_to_check exists in ", join ', ', @int_array;
}

请参阅List::Util

答案 3 :(得分:0)

if ( grep /^80$/, @int_array ) {
    ...
}

答案 4 :(得分:0)

如果您使用的是Perl 5.10或更高版本,则可以使用smart match运算符~~

my $found = (80 ~~ $in_array);