2009-08-11 75 views

回答

39

括号改变,其中所述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/ 
+0

'scalar @ array'是'@ array'中元素的个数 – 2009-08-11 20:08:45

1

grep返回一个列表。将标量变量名置于圆括号内时,Perl会将该整个l值视为列表,因此它将列表中的第一个值分配给该变量。

如果你有在括号其他标量,你会得到从grep“回归阵中第二,第三等其中的值:

my ($index, $foo, $bar) = grep { $array[$_] eq $search_for } 0..$#array; 
+3

grep返回一个数组。但只在数组上下文中。 – innaM 2009-08-11 19:51:37

+0

而在标量上下文中,它返回匹配返回true的次数,所以真正的标量化数组并不重要。 – Plutor 2009-08-11 19:55:10

+1

@Plutor:文档明确指出'grep'做什么,因此没有理由发布不准确的描述。 – 2009-08-11 20:03:32

8

括号为grep一个list contextgrep将实际返回表达式为真的元素列表,而不仅仅是表达式为真的次数。

+0

s /数组上下文/列表上下文/ – 2009-08-11 20:02:48

+0

方式更好。谢谢。 – innaM 2009-08-11 20:24:52

+0

不客气。 – 2009-08-11 20:39:28

7

我认为你是从List::MoreUtils寻找first_index

use List::MoreUtils qw(first_index); 

# ... 

my $index = first_index { $_ eq $search_for } @array; 
5

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; 
} 
1

另外,我觉得用grep只是为了找到的第一个实例是有点低效率的,因为它仍然穿行并在数组的每个元素上运行回调。特别是如果你的数组很长,你最好写一个循环,否则使用上面提到的List :: MoreUtils。

相关问题