Как я могу напечатать хэш хэшей хэшей в Perl? - PullRequest
2 голосов
/ 30 ноября 2009

У меня есть $map{k1}{k2}{k3}{k4}.

Как правильно написать цикл для печати всех значений? Следующее не работает.

for my $k1 (sort keys %tripletsCountMap) {
    for my $k2 (sort keys %$tripletsCountMap{k1}){
        for my $k3 (sort keys %$tripletsCountMap{k1}{k2}) {
            for my $k4 (sort keys %$tripletsCountMap{k1}{k3}{k3}){
                print "$k1 $k2 $k3 $k4\n";
            }
        }
    }
}

Ответы [ 8 ]

12 голосов
/ 30 ноября 2009

Обратите внимание, что существует разница между k1 и $k1.

for my $k1 (sort keys %tripletsCountMap) {
    for my $k2 (sort keys %{ $tripletsCountMap{$k1} }){
        for my $k3 (sort keys %{ $tripletsCountMap{$k1}{$k2} }) {
            for my $k4 (sort keys %{ $tripletsCountMap{$k1}{$k2}{$k3} }){
                printf "$k1 $k2 $k3 $k4: $tripletsCountMap{$k1}{$k2}{$k3}{$k4}\n";
            }
        }
    }
}

Еще лучше:

use Data::Dumper;
print Dumper \%tripletsCountMap;

И почему вы сортируете ключи? Я понимаю точку @ysth в комментариях ниже. У меня просто нет привычки сортировать ключи хэша, когда я их перебираю, если только нет явного требования, связанного с выводом.

4 голосов
/ 30 ноября 2009

При использовании% для разыменования выражения выражение должно быть заключено в {}, если это не простой скаляр (например, %$href).

Рекомендую прочитать http://perlmonks.org/?node=References+quick+reference.

4 голосов
/ 30 ноября 2009

Если это для отладки или аналогичных целей, вероятно, лучше использовать Data::Dumper для подобных вещей. Он достаточно умен, чтобы проследить структуру данных и понять ее правильно.

2 голосов
/ 30 ноября 2009

Самосвал бедняков:

sub trace {
    my ( $val, $path ) = @_;
    my $ref = ref $val;
    if ( $ref eq '' ) {
        print "$path = $val\n";
    }
    elsif ( $ref eq 'HASH' ) {
        trace( $val->{$_}, $path . "{$_}" ) for keys %$val;
    }
    elsif ( $ref eq 'ARRAY' ) {
        trace( $val->[$_], $path . "[$_]" ) for 0 .. $#$val;
    }
    else {
        warn "I don't know what to do with $ref at $path\n";
    }
}

trace($map, '$map->');
1 голос
/ 30 ноября 2009

$ k1 - переменная, k1 - голое слово .

perl -e '%h = (1 => 2, "k1" => 3); $k1 = 1; printf "%d %d\n", $h{$k1}, $h{k1}'

2 3

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

perl -e '$h = {1 => 2, "k1" => 3}; $k1 = 1; printf "%d %d\n", $h->{$k1}, $h->{k1}'

2 3

Если вы написали что-то вроде ничего не будет работать, как ожидалось:

perl -e '%h = {1 => 2, "k1" => 3}; $k1 = 1; printf "%d %d\n", $h->{$k1}, $h->{k1}'

0 0

Если голое слово не является проблемой (возможно, так оно и есть), то вам следует тщательно проверить, как вы построили свою карту.

0 голосов
/ 23 марта 2014

еще один способ:

 while (my ($first,$second) = each (%hash_hash_hash_hash)) {
    while (my ($second, $third) = each (%$second)) {
        while (my ($third, $fourth) = each (%$third)) {
            while (my ($fourth, $value) = each (%$fourth)) {
                print "$first\t$second\t$third\t$fourth\t$value\n";
            }
        }
    }
}
0 голосов
/ 15 апреля 2013

вы можете использовать следующий код: это будет работать

while(my($key1,$value1)=each(%hash_hash)){
  while(my($key2,$value2)=each(%$value1)){
       print $key1."=".$key2."=".$value2."\n";
  }

}

0 голосов
/ 30 ноября 2009

Вы печатаете все ключи, но не окончательное значение.

В самый внутренний цикл добавить:


my $val = $map{$k1}{$k2}{$k3}{$k4};
print "$val\n"; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...