如何在不使用perl中的键的情况下查找散列中是否存在值?

时间:2018-06-05 13:44:26

标签: perl hash hashmap hashtable

我有像这样的哈希映射

my $name = 'AUS'; #dynamic values
my %hash = { 'a'=>{
                  'x'=> {
                         '1' =>'US'
                         '2' =>'UK'
                        }
                  'y'=>{
                          '1' =>'AFRICA'
                          '2' =>'AUS'
                       }
                   }
            'b'=>{
                   'x' =>{
                           '1' =>'US'
                           '2' =>'UK'
                         }
                 }
           };

我试图找出名称在每列的哈希值中是唯一的

foreach my $key(keys %hash)
{
   if($name ne $hash{}{}{}) #is name unique in whole hash?
   {
      print "something";
   }
   else
   {
      print "nothing";
   }
}

一切都很好,但是当涉及到'b'键时,它会检查AUS是否存在并打印“某些东西”但我希望它也检查'a'键以查看是否有'AUS'值。那么,如何检查$ name是否存在于整个哈希中(我不能使用通过键值对查找,因为我试图在每列中查找和打印)?

2 个答案:

答案 0 :(得分:5)

这里没有灵丹妙药。您必须遍历哈希并检查每个值。有很多方法可以做到这一点,而你使用的方法则取决于你的哈希源的填充方式。

递归解决方案是:

#!/usr/bin/env perl
use strict;
use warnings;   
my $name = 'AUS';

use Data::Dumper;

my %hash = ( 'a'=>{
                  'x'=> {
                         '1' =>'US',
                         '2' =>'UK'
                        },
                  'y'=>{
                          '1' =>'AFRICA',
                          '2' =>'AUS'
                       }
                   },
            'b'=>{
                   'x' =>{
                           '1' =>'US',
                           '2' =>'UK'
                         }
                 }
           );

my %count_of;

sub traverse {
   my ( $input_hash ) = @_; 
   foreach my $sub ( values %{$input_hash} ) { 
      if (ref $sub) { 
         traverse ($sub);
      }
      else  {
         $count_of{$sub}++;
      }
   }
}

traverse (\%hash); 
print Dumper \%count_of;

print "$name is unique\n" if $count_of{$name} == 1; 

因为这是递归的,所以它会走到任何深度。哈希,但这可能不完全适合你的用例。

然而,你在谈论专栏这一事实告诉我,这个哈希是从其他地方填充的 - 我建议你看一下这个人口过程,因为它很可能是这样的。是一个更好的地方开始挑选特定的价值计数。

如果您需要更通用的查找表:

my @unique_elements = grep { $count_of{$_} == 1 } sort keys %count_of;
print Dumper \@unique_elements;
my %is_unique = map { $_ => 1 } @unique_elements; 
print Dumper \%is_unique;

print "$name is unique\n" if $is_unique{$name};

答案 1 :(得分:0)

如果我理解正确你想要这样的东西:

use strict;
use warnings;
my $name = 'AUS'; #dynamic values
my %hash = ( 'a'=>{
                  'x'=> {
                         '1' =>'US',
                         '2' =>'UK'
                        },
                  'y'=>{
                          '1' =>'AFRICA',
                          '2' =>'AUS'
                       }
                   },
            'b'=>{
                   'x' =>{
                           '1' =>'US',
                           '2' =>'UK'
                         }
                 }
           );



my @val = grep {$_ eq $name} map {my $x=$_; map {my $y=$_; map {$hash{$x}->{$y}->{$_}} keys %{$hash{$x}->{$_}}} keys %{$hash{$_}}} keys %hash;
if(@val == 0) {
    print "$name not found";
}
elsif(@val == 1) {
    print "$name is unique";
}
else {
    print "$name is not unique";
}