有时在Perl中,我编写了一个for
/ foreach
循环,该循环遍历值以对照列表检查值。第一次命中后,就可以退出循环,因为我们已经满足了我的测试条件。例如,以下简单代码:
my @animals = qw/cat dog horse/;
foreach my $animal (@animals)
{
if ($input eq $animal)
{
print "Ah, yes, an $input is an animal!\n";
last;
}
}
# <-----
有没有一种优雅的方法-可能是一个重载的关键字-处理“ for循环到达最后一个元素”?在上方的箭头上放些东西了吗?
我可以想到实现此目的的方法,例如创建/设置其他$found
变量并在末尾对其进行测试。...但是我希望Perl可以内置其他东西,例如:>
foreach my $animal (@animals)
{
if ($input eq $animal)
{
print "Ah, yes, an $input is an animal!\n";
last;
}
} finally {
print "Sorry, I'm not sure if $input is an animal or not\n";
}
这将使测试更加直观。
答案 0 :(得分:3)
您可以像这样用标记块包装循环:
outer: {
foreach my $animal (@animals) {
if ($input eq $animal) {
print "Ah, yes, an $input is an animal!\n";
last outer;
}
}
print "no animal found\n";
}
答案 1 :(得分:2)
这不是最好的解决方案,但有时它有助于迭代索引。
for my $i (0..$#animals) {
my $animal = $animals[$i];
...
}
然后,您可以检查索引是0
(第一遍)还是$#a
(最后一遍)。
答案 2 :(得分:1)
只需在循环中设置一个变量,以便您可以检查它是否已设置并稍后对其进行操作:
my $found;
foreach my $animal (@animals) {
if ($input eq $animal) {
$found = $animal;
last outer;
}
}
print defined $found ? "Ah, yes, an $input is an animal!\n" : "no animal found\n";
但是对于这个特殊的问题,如@choroba所说,只需使用List :: Util中的first
(或any
)函数。或者,如果您要检查大量输入,则检查散列会更容易。
my %animals = map { ($_ => 1) } qw/cat dog horse/;
print exists $animals{$input} ? "Ah, yes, an $input is an animal!\n" : "no animal found\n";
答案 3 :(得分:1)
我将其保留为Old School,并使用一个众所周知的C惯用法(在第一个语句中分割for循环,在while循环中分割)。
#!/usr/bin/env perl
use strict;
use warnings;
my $input = 'lion';
my @animals = qw/cat dog horse/;
my $index = 0;
while ($index < scalar @animals) {
if ($animals[ $index++ ] eq $input) {
print "Ah, yes, an $input is an animal!\n";
last;
}
}
if ($index == scalar @animals) {
print "Sorry, I'm not sure if $input is an animal or not\n";
}
因此,“对不起,我不确定狮子是否是动物”会很自然地出现。 希望这可以帮助。问候,M。
答案 4 :(得分:1)
首先将是最少的开销; eval避免将所有内容嵌套在if块中;换行符,因为您可能并不十分在意这行不是动物。
eval
{
my $found = first { check for an animal } @animalz
or die "Sorry, no animal found.\n";
# process an animal
1
}
// do
{
# deal with non-animals
};