Как мне создать массив хэшей и перебрать их в Perl? - PullRequest
4 голосов
/ 24 августа 2009

Я пытаюсь создать массив хэшей, но у меня возникают проблемы с циклическим перебором массива. Я пробовал этот код, но он не работает:

for  ($i = 0; $i<@pattern; $i++){
  while(($k, $v)= each $pattern[$i]){
    debug(" $k: $v");
  }
}

Ответы [ 3 ]

24 голосов
/ 24 августа 2009

Во-первых, почему вы не use strict и warnings? Следующие строки должны быть в начале каждой создаваемой вами Perl-программы, сразу после #!/usr/bin/perl. Всегда .

use strict;
use warnings;

И я знаю, что это не так, потому что я уверен, что вы получите хорошие сообщения об ошибках из strict и warnings из этого, а также из многих других мест в вашем коде, судя по вашему переменное использование.

Во-вторых, почему ты не делаешь это:

for my $i (@pattern) {
  ..
}

Это проходит через каждый элемент в @pattern, присваивая им $i по одному за раз. Затем, в вашем цикле, когда вы хотите определенный элемент, просто используйте $i. Изменения в $i будут отражены в @pattern, а когда цикл выйдет, $i выйдет из области видимости, по сути, очистившись после себя.

В-третьих, ради любви к Ларри Уоллу, , пожалуйста, объявите свои переменные с помощью my для их локализации. Это действительно не так сложно, и я обещаю, что это делает тебя лучше.

И, наконец, в-четвертых, ваш массив хранит ссылки на хэши, а не хэши. Если бы они хранили хэши, ваш код был бы неправильным, потому что хэши начинаются с %, а не $. Как таковые, ссылки (любого рода) являются скалярными значениями и поэтому начинаются с $. Так что нам нужно разыменовать их, чтобы получить хэши:

for my $i (@pattern) {
  while(my($k, $v) = each %{$i}) {
    debug(" $k: $v");
  }
}

Или, по-вашему:

for  (my $i = 0; $i<@pattern; $i++) { # added a my() for good measure
  while(my($k, $v) = each %{$pattern[$i]}) {
    debug(" $k: $v");
  }
}
6 голосов
/ 24 августа 2009

Попробуйте вместо этого:

for my $hashref (@pattern) {
    for my $key (keys %$hashref) {
        debug "$key: $hashref->{$key}";
    }
}

Самая большая проблема с тем, что вы пытались, была each $pattern[$i]. Функция каждая ожидает, что хеш будет работать, но $pattern[$i] возвращает хэш-ссылку (то есть ссылку на хеш). Вы можете исправить свой код, разыменовав $pattern[$i] как хеш:

while(my($k, $v) = each %{$pattern[$i]}) {

Также, остерегаясь каждой функции, она может оставить итератор хеша в неполном состоянии .

4 голосов
/ 24 августа 2009

См. Документацию для поваренной книги по структурам данных perl: perldoc perldsc

...