我不理解Programming Perl 3e中此函数的最后一行。
以下是通过返回传递给它的所有散列中出现的键列表,编写一个执行某种集合交集的函数的方法:
@common = inter( \%foo, \%bar, \%joe ); sub inter { my %seen; for my $href (@_) { while (my $k = each %$href) { $seen{$k}++; } } return grep { $seen{$_} == @_ } keys %seen; }
我理解%seen
是一个散列,它将每个键映射到在为函数提供的任何散列中遇到的次数。
答案 0 :(得分:16)
grep
将传递给它的列表(在这种情况下,在任何hashrefs中看到的每个元素);并返回仅列表中表达式为true的元素的列表(将$_
变量本地设置为列表中的每个元素)。
让我们看看如何评估该表达式:
@_
是传递给子例程的所有参数的数组 - 在我们的示例中是传入的哈希引用列表。
在$seen{$_} == @_
表达式中,该列表被强制转换为scalar context(由于==
)。
在标量上下文中使用时,列表会计算列表中元素的数量 - 在上面的示例调用中,为3,因为传入了3个hashref。
因此,对于%seen
中的每个键(例如,在任何N个hashref中看到的每个键);表达式$seen{$_} == @_
在数字上比较了在散列中看到元素的次数与散列的总数 - 当然,如果元素在所有传入的散列中,它将是相等的,因此我们想要的交叉点的成员。
因此,为了总结分析,grep将返回在每个哈希中出现的所有键的列表(也称为N次,其中N是哈希值)。例如。一个十字路口。
答案 1 :(得分:3)
grep block list
这将依次将块应用于列表的每个元素,该元素的别名为$ _。如果块返回true,则将元素添加到返回的数组中。
在这种情况下:
grep { $seen{$_} == @_ } keys %seen
该块为$seen{$_} == @_
,它将查看的哈希值与@_
进行比较。 @_
在标量上下文中进行计算,从而返回@_
数组中的元素数。 @_
表示当前函数的参数。在这种情况下( \%foo, \%bar, \%joe )
,它在标量上下文中返回3
。我们的列表是keys %seen
,这是一个包含%seen
中所有键的数组。
%seen
相关联的值
该键等于数量
传递给此函数的元素“%seen
相关联的值
该密钥为3
“%seen
的所有密钥
值3
,即%seen
中的所有键
存在于3中的每一个中
传递给此函数的hashrefs“答案 2 :(得分:2)
该函数的目的是找到传递给它的所有哈希中出现的元素。
从grep
返回的列表的最后一行keys %seen
。要确定给定键是否出现在传递给函数的所有哈希值中,我们可以将%seen
中的键值与inter
的参数数量进行比较。
在grep
块中,$_
设置为keys
列表的每个元素,并针对某些条件进行测试。
标量上下文中的数组计算其长度。 @_
是传递给子例程的参数数组。 ==
运算符将其操作数放在标量上下文中,因此我们只需将$seen{$_}
的值与长度@_
进行比较即可。如果它们是相同的,则该键出现在所有哈希中。