Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Perl:测试值是否在数组中的好方法?_Arrays_Perl - Fatal编程技术网

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

Arrays Perl:测试值是否在数组中的好方法?,arrays,perl,Arrays,Perl,如果我有一个数组: @int_array = (7,101,80,22,42); 如何在不循环每个元素的情况下检查整数值80是否在数组中?如果不循环,则不能。这就是数组的一部分含义。您可以使用grep或smartmatch使用隐式循环,但仍然存在一个循环。如果要避免循环,请改用散列(或另外使用) if ( grep /^80$/, @int_array ) { ... } 在使用smartmatch之前,请注意: : smartmatch系列功能现在处于试验阶段 Smart matc

如果我有一个数组:

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

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

如果不循环,则不能。这就是数组的一部分含义。您可以使用grep或smartmatch使用隐式循环,但仍然存在一个循环。如果要避免循环,请改用散列(或另外使用)

if ( grep /^80$/, @int_array ) {
    ...
}
在使用smartmatch之前,请注意:

:

smartmatch系列功能现在处于试验阶段

Smart match在v5.10.0中添加,并在v5.10.1中进行了重大修改,这一直是一个常见的投诉点。尽管有许多方法可以使用它,但对于Perl的用户和实现者来说,它也被证明是有问题和令人困惑的。关于如何最好地解决这一问题,已经提出了一些建议。很明显,smartmatch几乎肯定会在未来改变或消失。不建议依赖其当前行为

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


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

my $found = (80 ~~ $in_array);
CPAN溶液:使用

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

@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的这篇SO帖子),智能匹配是短路,所以它和5.10的“任何”解决方案一样好

  • grep
    解决方案在整个列表中循环,即使1000000长列表的第一个元素匹配
    任何
    都会在找到第一个匹配项时短路并退出,因此效率更高。最初的海报明确地说“不通过每个元素循环”

  • 如果需要进行大量查找,则创建哈希的一次性沉没成本会使哈希查找方法比其他方法更有效。看


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

#!/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;
}

请参阅。

一般使用grep,因为这不是一个好主意;它将分配一个额外的列表来保存grep的结果,并且即使第一个元素是80,它也会继续遍历数组。@gab:在典型情况下,继续遍历数组比提前退出要便宜。@gab:一般来说,我避免像C一样编写Perl——如果Perl提供了方便的工具,而我不使用它们,为什么要使用Perl?@kemp:我完全同意——但是,Perl快速检查是否存在值的方法是使用哈希而不是列表。哈希不能替代列表,否则我们根本就不会使用列表++。智能匹配(或者可能是列表::MoreUtils中的某个内容)是一种方法。为了完整起见,下面是使用散列的方法:my@array=1..1000;我的%hash;未定义@hash{@array};如果存在$hash{10},则说“10在数组中!”
undef@hash{@array}
可以工作,但实际上并没有文档记录这样做。改用
@hash{@array}=()
。我不确定你的意思,所以我在谷歌上搜索发现:谢谢你的更正,伊斯特!grep是坏的-OP明确地说“没有循环通过每个元素”。@DVK:这就是为什么我说“你不能”。smartmatch或其他任何东西与grep或for一样是一个循环(可能会遍历每个元素)。这取决于数组的大小和需要进行的检查的数量。解析外部模块的效率可能低于完整的
grep
。此外,如果效率是主要考虑因素,只需使用
last
@kemp-IIRC,对每个
foreach
进行手动
List::MoreUtils就可以实现XS。这比用最后一个的foreach快。如果使用本机Perl,模块可能就是这样做的
@int_array{@int_array} = 1;
foreach my $lookup_value (@lookup_values) {
    print "found $lookup_value\n" if exists $int_array{$lookup_value}
}
#!/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;
}