我试图找出一种方法来检查数组中值的存在,而不遍历数组。
我正在读取一个文件的参数。我有一长串不想处理的参数。我把这些不需要的参数放在一个数组@badparams中。
我想读取一个新的参数,如果它不存在于@badparams,处理它。如果@badparams中存在,请转到下一次读取。
我试图找出一种方法来检查数组中值的存在,而不遍历数组。
我正在读取一个文件的参数。我有一长串不想处理的参数。我把这些不需要的参数放在一个数组@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开始的值这里可以放入任何正则表达式
其他回答
如果你需要知道数组中每个元素的数量,除了该元素的存在,你可以使用
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的数量
my @badparams = (1,2,5,7,'a','zzz');
my $badparams = join('|',@badparams); # '|' or any other character not present in params
foreach my $par (4,5,6,7,'a','z','zzz')
{
if ($badparams =~ /\b$par\b/)
{
print "$par is present\n";
}
else
{
print "$par is not present\n";
}
}
您可能需要检查数字前导空格的一致性
尽管使用起来很方便,但转换为哈希的解决方案似乎消耗了相当多的性能,这对我来说是个问题。
#!/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)
这篇博文讨论了这个问题的最佳答案。
作为一个简短的总结,如果你可以安装CPAN模块,那么最有可读性的解决方案是:
any(@ingredients) eq 'flour';
or
@ingredients->contains('flour');
然而,更常见的习语是:
any { $_ eq 'flour' } @ingredients
但是请不要使用first()函数!它根本没有表达你代码的意图。不要使用~~“智能匹配”操作符:它已经坏了。不要使用grep()或带散列的解决方案:它们遍历整个列表。
Any()一旦找到你的值就会停止。
查看博客文章了解更多细节。
你可以在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:
}