Как узнать, существует ли значение в хэше, не используя ключ в Perl? - PullRequest
0 голосов
/ 05 июня 2018

У меня есть такая хеш-карта

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 голосов
/ 05 июня 2018

Здесь нет волшебной пули.Вы должны пересмотреть свой хэш и проверить каждое значение.Существует множество подходов к этому, и то, что вы используете, скорее зависит от того, как заполняется ваш хэш-источник.

Рекурсивным решением будет:

#!/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};
0 голосов
/ 05 июня 2018

если я правильно понимаю, вы хотите что-то вроде этого:

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