【发布时间】:2014-04-24 21:40:48
【问题描述】:
我有一个数组和一个哈希。我想将散列的键与数组的元素相匹配。
我找到了一个表达式来 grep 与数组匹配的所有键。它有效,但我不确定我是否理解它是如何工作的。你能解释一下grep之后发生了什么吗?
数组@text 和散列%sys 已经定义。
my @new_array = grep { exists $sys{$_} ? $sys{$_} : 0 } @text;
【问题讨论】:
我有一个数组和一个哈希。我想将散列的键与数组的元素相匹配。
我找到了一个表达式来 grep 与数组匹配的所有键。它有效,但我不确定我是否理解它是如何工作的。你能解释一下grep之后发生了什么吗?
数组@text 和散列%sys 已经定义。
my @new_array = grep { exists $sys{$_} ? $sys{$_} : 0 } @text;
【问题讨论】:
您找到的代码过于复杂。它可能/应该是*:
my @new_array = grep { $sys{$_} } @text;
grep 函数将一个列表(在本例中为 @text 数组的内容)处理为一个新列表,该列表仅包含中间表达式计算为真值的元素。默认值$_依次设置为每个列表项,以便表达式可以考虑列表内容。
您示例中的表达式包含一个三元运算符?,如果第一部分为真,则计算为: 之前的项目,如果为假,则计算其后的值。因此,在您的情况下,它会检查每个键是否在 %sys 散列中,如果存在则评估散列条目的查找,如果不存在则评估为 0(假值)。在 grep 中的功能上,这应该与 $sys{$_} 相同,因为通过查找不存在的键的值获得的 undef 也是错误值。
* 但是,有一个警告 - 如果 %sys 绑定到 Perl 类并且覆盖了一些哈希函数,则为 exists 和哈希查找调用不同的哈希方法。因此,在这种情况下,性能或行为可能会有所不同。
【讨论】:
0 - 如果没有必要,它可能不会这样做。
grep 中没有替代品,只是评估为真/假。它也不改变每个假值 - 只有当%sys 中没有键时。如果有值$sys{'foo'} = undef; 或$sys{'foo'} = '';,那么它不会更改为0,但仍会评估为undef 或块中的空字符串(如果@text 包含'foo')。
map 块迁移到 0 是有用的