让我说我有这个
#!/usr/bin/perl
%x = ('a' => 1, 'b' => 2, 'c' => 3);
我想知道值2是%x
中的哈希值。
这是怎么做到的?
答案 0 :(得分:17)
从根本上说,哈希是为解决相反问题而优化的数据结构,知道键 2是否存在。但是如果不知道就很难判断,所以我们假设不会改变。
此处提供的可能性取决于:
grep $_==2, values %x
(也拼写为grep {$_==1} values %x
)将返回哈希中存在的2个列表,或者在标量上下文中返回匹配数。在条件中作为布尔值进行评估,它可以产生您想要的结果
grep
适用于我记忆中的Perl版本。use List::Util qw(first); first {$_==2} values %x
仅返回第一个匹配项,如果没有则返回undef
。这使它更快,因为它会在成功时短路(停止检查元素)。这不是2的问题,但要注意返回的元素不一定要求为布尔值true。在这些情况下使用defined
List::Util
是自5.8以来Perl核心的一部分。use List::MoreUtils qw(any); any {$_==2} values %x
完全返回您作为布尔值请求的信息,并表现出短路行为
List::MoreUtils
可从CPAN获得。2 ~~ [values %x]
完全返回您作为布尔值请求的信息,并表现出短路行为
自5.10以来,Smart matching在Perl中可用。构造一个将值映射到键的哈希,并将其用作自然哈希来测试键的存在。
my %r = reverse %x;
if ( exists $r{2} ) { ... }
使用上面的反向查找。你需要保持它是最新的,这是作为练习给读者/编辑。 (提示:价值冲突很棘手)
答案 1 :(得分:10)
使用智能匹配(Perl版本5.10或更高版本)的更短答案:
print 2 ~~ [values %x];
答案 2 :(得分:8)
my %reverse = reverse %x;
if( defined( $reverse{2} ) ) {
print "2 is a value in the hash!\n";
}
如果您想找出值为2的键:
foreach my $key ( keys %x ) {
print "2 is the value for $key\n" if $x{$key} == 2;
}
答案 3 :(得分:7)
到目前为止,每个人的答案都不是以绩效为导向的。虽然智能匹配(~~
)解决方案短路(例如,在找到某些内容时停止搜索),但grep
解决方案不会。
因此,这是一个解决方案,它可能在5.10之前具有更好的性能,没有智能匹配运算符:
use List::MoreUtils qw(any);
if (any { $_ == 2 } values %x) {
print "Found!\n";
}
请注意,这只是在这种情况下搜索列表(values %x
)的一个具体示例,因此,如果您关心性能,则在列表中搜索的标准性能分析将应用为{{ 3}}
答案 4 :(得分:5)
my %x = ('a' => 1, 'b' => 2, 'c' => 3);
if (grep { $_ == 2 } values %x ) {
print "2 is in hash\n";
}
else {
print "2 is not in hash\n";
}
另请参阅:perldoc -q hash
答案 5 :(得分:3)
结果是$ count:
my $count = grep { $_ == 2 } values %x;
这不仅会告诉您它是否是散列中的值,而是它作为值出现的次数。或者你也可以这样做:
my $count = grep {/2/} values %x;