假设我有这个
#!/usr/bin/perl
%x = ('a' => 1, 'b' => 2, 'c' => 3);
Run Code Online (Sandbox Code Playgroud)
我想知道值2是否是哈希值%x.
怎么做的?
JB.*_*JB. 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起,Perl中提供了构造一个将值映射到键的哈希,并将其用作自然哈希来测试键的存在.
my %r = reverse %x;
if ( exists $r{2} ) { ... }
Run Code Online (Sandbox Code Playgroud)
使用上面的反向查找.你需要保持最新,这是作为读者/编辑的练习.(提示:价值冲突很棘手)
mob*_*mob 10
使用智能匹配(Perl版本5.10或更高版本)的更短答案:
print 2 ~~ [values %x];
Run Code Online (Sandbox Code Playgroud)
my %reverse = reverse %x;
if( defined( $reverse{2} ) ) {
print "2 is a value in the hash!\n";
}
Run Code Online (Sandbox Code Playgroud)
如果要查找值为2的键:
foreach my $key ( keys %x ) {
print "2 is the value for $key\n" if $x{$key} == 2;
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,每个人的答案都不是以绩效为导向的.虽然smart-match(~~)解决方案短路(例如,当找到某些东西时停止搜索),但grep那些没有.
因此,对于没有智能匹配运算符的5.10之前的Perl可能具有更好性能的解决方案:
use List::MoreUtils qw(any);
if (any { $_ == 2 } values %x) {
print "Found!\n";
}
Run Code Online (Sandbox Code Playgroud)
请注意,这只是values %x在这种情况下搜索列表()的一个具体示例,因此,如果您关心性能,则在列表中搜索的标准性能分析适用于此答案中详细讨论
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";
}
Run Code Online (Sandbox Code Playgroud)
也可以看看: perldoc -q hash