好像我应该可以用地图来做这件事,但实际的细节让我不知所措。
我有一个数组中的字符串列表,零或其中一个可能有一个哈希值。
所以不要这样做:
foreach $str ( @strings ) {
$val = $hash{$str} if $hash{$str};
}
可以使用地图替换为单行吗?
答案 0 :(得分:6)
@values = grep { $_ } @hash{@strings};
说明您只想要 true 值。
将此更改为
@values = grep { defined } @hash{@strings};
如果你想跳过未定义的值。
答案 1 :(得分:4)
当然,它是:
map { $val = $hash{$_} } @strings;
也就是说,@strings
的每个值都依次设置在$_
中(而不是像你的foreach中的$str
)。
当然,这并没有太大作用,因为你在循环中没有使用$val
的值做任何事情,而且我们没有捕获map
返回的列表。
如果你只是想生成一个值列表,那就是:
@values = map { $hash{$_} } @strings;
但使用哈希切片更简洁:
@values = @hash{@strings};
编辑:正如评论中所指出的,如果@strings
包含的值不是哈希中的键,那么@values
将在这些位置获得undefs。如果这不是您想要的,请参阅Hynek's answer以获得解决方案。
答案 2 :(得分:3)
我习惯这样做:
@values = map { exists $hash{$_} ? $hash{$_} : () } @strings;
但我没有看到任何错误
push @values, $hash{$_} for grep exists $hash{$_}, @strings;
或
@values = @hash{grep exists $hash{$_}, @strings};
答案 3 :(得分:1)
map { defined $hash{$_} && ( $val = $hash{$_})} @strings;