以下代码片段将搜索数组中第一次出现值的索引。但是,当$ index周围的括号被删除时,它不能正常工作。我究竟做错了什么?为什么我的Perl grep不会返回第一个匹配项?
my ($index) = grep { $array[$_] eq $search_for } 0..$#array;
以下代码片段将搜索数组中第一次出现值的索引。但是,当$ index周围的括号被删除时,它不能正常工作。我究竟做错了什么?为什么我的Perl grep不会返回第一个匹配项?
my ($index) = grep { $array[$_] eq $search_for } 0..$#array;
括号改变,其中所述grep
从标量环境评估,以列表上下文的上下文。在标量环境下,grep
返回表达式为真的次数。在列表上下文中,它返回表达式为真的元素。
以下重点差异背景下使得:
my $x = grep {/foo/} @array; # the number of things that match /foo/
my ($x) = grep {/foo/} @array; # the first thing that matches /foo/
my @foo = grep {/foo/} @array; # all the things that match /foo/
my (@foo) = grep {/foo/} @array; # all the things that match /foo/
grep
返回一个列表。将标量变量名置于圆括号内时,Perl会将该整个l值视为列表,因此它将列表中的第一个值分配给该变量。
如果你有在括号其他标量,你会得到从grep
“回归阵中第二,第三等其中的值:
my ($index, $foo, $bar) = grep { $array[$_] eq $search_for } 0..$#array;
括号为grep
一个list context。 grep
将实际返回表达式为真的元素列表,而不仅仅是表达式为真的次数。
s /数组上下文/列表上下文/ – 2009-08-11 20:02:48
方式更好。谢谢。 – innaM 2009-08-11 20:24:52
不客气。 – 2009-08-11 20:39:28
我认为你是从List::MoreUtils寻找first_index
:
use List::MoreUtils qw(first_index);
# ...
my $index = first_index { $_ eq $search_for } @array;
grep的功能列表上下文和标量上下文中的行为不同。此记录在perldoc -f grep
:
评估块或EXPR对于列表中的每个元件(局部 设置$ _每个元素),并返回一个由该表达式评估 为true这些元素的列表值 。在标量上下文中,返回 表达式为真的次数。
您可以自己复制这与命名不良wantarray功能:
sub my_grep {
my $sub = shift;
my @return;
for my $item (@_) {
push @return if $sub->($item);
}
return @return if wantarray;
return scalar @return;
}
另外,我觉得用grep只是为了找到的第一个实例是有点低效率的,因为它仍然穿行并在数组的每个元素上运行回调。特别是如果你的数组很长,你最好写一个循环,否则使用上面提到的List :: MoreUtils。
'scalar @ array'是'@ array'中元素的个数 – 2009-08-11 20:08:45