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

如何在不使用perl中的键的情况下查找哈希中是否存在该值?,perl,hash,hashmap,hashtable,Perl,Hash,Hashmap,Hashtable,我有一个这样的散列图 my $name = 'AUS'; #dynamic values my %hash = { 'a'=>{ 'x'=> { '1' =>'US' '2' =>'UK' } 'y'=>{

我有一个这样的散列图

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(我无法使用“通过键值对查找”,因为我试图在每列中查找和打印)?

如果我理解正确,您希望这样:

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";
}

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

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";
}

这里没有灵丹妙药。您必须遍历哈希并检查每个值。有多种方法可以实现这一点,而您使用的方法相当依赖于哈希源的填充方式

递归解决方案是:

#!/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};

这里没有灵丹妙药。您必须遍历哈希并检查每个值。有多种方法可以实现这一点,而您使用的方法相当依赖于哈希源的填充方式

递归解决方案是:

#!/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};


那段代码没有编译。@Andrey用{a}{y}{2}代替{}{}{}和明显的语法错误扫描显示了唯一和非唯一键的预期输出?我还是不明白。那么您有几个@name,您想检查它们中的哪一个在散列引用的第三级上是唯一的?好的,那么为什么不从一个简单的数组开始,看看是否需要更详细的内容。您可以编写
my@data=map{chomp;[split/,/]}
来创建它,而且它的查询非常简单。该代码不会编译。@Andrey使用{a}{y}{2}而不是{}{}{}{}和明显的语法错误扫描您显示了唯一键和非唯一键的预期输出?我仍然不明白。那么您有几个@name,您想检查它们中的哪一个在散列引用的第三级上是唯一的?好的,那么为什么不从一个简单的数组开始,看看是否需要更详细的内容。您可以编写
my@data=map{chomp;[split/,/]}
来创建它,而且查询起来非常简单。这是一个很好的解决方案。此外,您不需要我的@values;哦,是的。第一次填充已找到元素的列表时,是否进行了此操作;我将删除它。如果您正在搜索哈希中不存在的内容,代码也会给出一个错误,这很容易修复。很好的解决方案。此外,您不需要我的@values;哦,是的。第一次填充已找到元素的列表时,是否进行了此操作;我将删除它。如果您正在搜索哈希中不存在的内容,代码也会给出一个错误,这很容易修复。这是一个很好的解决方案。但是您能够概括吗?我的意思是,当有x,y时,这很好,当有更多的时候会发生什么?我的$x和我的$y与散列的键无关。这些只是暂时的变量。这适用于x,y,z。。。只要有3个哈希级别。Sobrique解决方案适用于任何数量的次级级别。您的解决方案对我来说都适用,谢谢您在这里帮助我。我很感激它是一个伟大的解决方案。但您能概括一下吗?我的意思是,当有x,y时,这很好,当有更多的时候会发生什么?我的$x和我的$y与散列的键无关。这些只是暂时的变量。这适用于x,y,z。。。只要有3个哈希级别。Sobrique解决方案适用于任何数量的次级级别。您的解决方案对我来说都适用,谢谢您在这里帮助我。我非常感谢