我试图找出一种方法来检查数组中值的存在,而不遍历数组。

我正在读取一个文件的参数。我有一长串不想处理的参数。我把这些不需要的参数放在一个数组@badparams中。

我想读取一个新的参数,如果它不存在于@badparams,处理它。如果@badparams中存在,请转到下一次读取。


当前回答

@files是一个已存在的数组

my @new_values =  grep(/^2[\d].[\d][A-za-z]?/,@files);

print join("\n", @new_values);

print "\n";

/ ^ 2 \ [d]。[\ d] [A-za-z]吗?/ =从2开始的值这里可以放入任何正则表达式

其他回答

@files是一个已存在的数组

my @new_values =  grep(/^2[\d].[\d][A-za-z]?/,@files);

print join("\n", @new_values);

print "\n";

/ ^ 2 \ [d]。[\ d] [A-za-z]吗?/ =从2开始的值这里可以放入任何正则表达式

你可以在Perl 5.10中使用smartmatch特性,如下所示:

对于文字值查找,执行下面的操作即可。

if ( "value" ~~ @array ) 

对于标量查找,执行以下操作将与上述工作一样。

if ($val ~~ @array)

对于内联数组做下面,将工作如上。

if ( $var ~~ ['bar', 'value', 'foo'] ) 

在Perl 5.18中,smartmatch被标记为实验性的,因此你需要通过在你的脚本/模块中添加以下内容来打开实验性的pragma来关闭警告:

use experimental 'smartmatch';

或者,如果你想避免使用smartmatch,那么就像Aaron说的那样使用:

if ( grep( /^$value$/, @array ) ) {
  #TODO:
}

方法1:grep(可能小心,而值是一个正则表达式)。

如果查看资源,尽量避免使用grep。

if ( grep( /^$value$/, @badparams ) ) {
  print "found";
}

方法二:线性搜索

for (@badparams) {
    if ($_ eq $value) {
       print "found";
       last;
    }
}

方法3:使用散列

my %hash = map {$_ => 1} @badparams;
print "found" if (exists $hash{$value});

方法四:smartmatch

(在Perl 5.10中添加,在Perl 5.18中标记为实验性)。

use experimental 'smartmatch';  # for perl 5.18
print "found" if ($value ~~ @badparams);

方法5:使用List::MoreUtils模块

use List::MoreUtils qw(any);
@badparams = (1,2,3);
$value = 1;
print "found" if any {$_ == $value} @badparams;

尽管使用起来很方便,但转换为哈希的解决方案似乎消耗了相当多的性能,这对我来说是个问题。

#!/usr/bin/perl
use Benchmark;
my @list;
for (1..10_000) {
    push @list, $_;
}

timethese(10000, {
  'grep'    => sub {
            if ( grep(/^5000$/o, @list) ) {
                # code
            }
        },
  'hash'    => sub {
            my %params = map { $_ => 1 } @list;
            if ( exists($params{5000}) ) {
                # code
            }
        },
});

基准测试输出:

Benchmark: timing 10000 iterations of grep, hash...
          grep:  8 wallclock secs ( 7.95 usr +  0.00 sys =  7.95 CPU) @ 1257.86/s (n=10000)
          hash: 50 wallclock secs (49.68 usr +  0.01 sys = 49.69 CPU) @ 201.25/s (n=10000)

如果你需要知道数组中每个元素的数量,除了该元素的存在,你可以使用

my %bad_param_lookup;
@bad_param_lookup{ @bad_params } = ( 1 ) x @bad_params;
%bad_param_lookup = map { $_ => $bad_param_lookup{$_}++} @bad_params;

然后对于@bad_params中的每个$i, $bad_param_lookup{$i}包含@bad_params中的$i的数量