这在perlfaq4对“如何判断某个元素是否包含在列表或数组中?”的回答中得到了回答。.
要搜索 perlfaq,您可以使用您喜欢的浏览器搜索perlfaq中所有问题的列表。
在命令行中,您可以使用 -q 开关切换到 perldoc 来搜索关键字。您会通过搜索“列表”找到答案:
perldoc -q list
(此答案的部分内容由 Anno Siegel 和 brian d foy 提供)
听到“in”这个词表明您可能应该使用散列而不是列表或数组来存储数据。哈希旨在快速有效地回答这个问题。数组不是。
话虽如此,有几种方法可以解决这个问题。在 Perl 5.10 及更高版本中,您可以使用智能匹配运算符来检查项目是否包含在数组或哈希中:
use 5.010;
if( $item ~~ @array )
{
say "The array contains $item"
}
if( $item ~~ %hash )
{
say "The hash contains $item"
}
对于早期版本的 Perl,您必须做更多的工作。如果您要对任意字符串值多次进行此查询,最快的方法可能是反转原始数组并维护一个哈希,其键是第一个数组的值:
@blues = qw/azure cerulean teal turquoise lapis-lazuli/;
%is_blue = ();
for (@blues) { $is_blue{$_} = 1 }
现在您可以检查是否 $is_blue{$some_color}. 首先将布鲁斯全部保存在哈希中可能是一个好主意。
如果这些值都是小整数,则可以使用简单的索引数组。这种数组将占用更少的空间:
@primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
@is_tiny_prime = ();
for (@primes) { $is_tiny_prime[$_] = 1 }
# or simply @istiny_prime[@primes] = (1) x @primes;
现在你检查 $is_tiny_prime[$some_number].
如果有问题的值是整数而不是字符串,则可以通过使用位字符串来节省大量空间:
@articles = ( 1..10, 150..2000, 2017 );
undef $read;
for (@articles) { vec($read,$_,1) = 1 }
现在检查 vec($read,$n,1) 对于某些 $n 是否为真。
这些方法保证了快速的单独测试,但需要重新组织原始列表或数组。只有当您必须针对同一个数组测试多个值时,它们才会得到回报。
如果您只测试一次,标准模块 List::Util 为此首先导出该函数。一旦找到元素,它就会停止工作。为了速度,它是用 C 语言编写的,它的 Perl 等效程序如下所示:
sub first (&@) {
my $code = shift;
foreach (@_) {
return $_ if &{$code}();
}
undef;
}
如果速度无关紧要,常见的习惯用法在标量上下文中使用 grep(它返回通过其条件的项目数)来遍历整个列表。不过,这确实有利于告诉您它找到了多少匹配项。
my $is_there = grep $_ eq $whatever, @array;
如果您想实际提取匹配元素,只需在列表上下文中使用 grep 即可。
my @matches = grep $_ eq $whatever, @array;