2010-11-10 4 views
1

У меня есть хэш, скажем, 20 значений.Итерировать через значения хеша в perl

Он инициализируется таким образом:

my $line = $_[0]->[0]; 

    foreach my $value ($line) { 
     print $value; 
    } 

Теперь, когда я пытаюсь получить значение каждого хэша в $ строке говорится: Использования неинициализированного значения в печати на file.pl линии 89

Есть ли способ итерации через каждое значение хэша?

Я также пробовал с:

my %line = $_[0]->[0]; 

    foreach my $key (keys %line) { 
     print %line->{$key}; 
    } 

Но это тоже не работает: Ссылка нашел где список даже размера ожидается в file.pl в строке 89

Кто-нибудь знает, что делать? Это не должно быть так сложно ...

+0

Я смущен. Конечно, мне кажется, что вы инициализировали скаляр, а не хэш. – Cascabel

+0

И в вашем втором примере вы пытаетесь сделать его хешем, но вы по-прежнему назначаете скаляр - может быть, это хэш ref? – Cascabel

+0

Используйте отладчик Perl и распечатайте свой список arglist с помощью команды 'x'. – tchrist

ответ

3

$line в вашем первом примере - это скаляр, а не хэш.

Если это хеш-ссылка, разыщите его с помощью %{$line}.

+1

А я вижу! Теперь он работает с: my $ line = $ _ [0] -> [0]; \t \t foreach my $ value (значения% {$ line}) { \t \t print $ value. "\ П"; \t} – baklap

9

Для перебора значений в хэш:

for my $value (values %hash) { 
    print $value; 
} 
3

Во-первых, вы должны понимать разницу между хэш, и ссылка хэш.

Вашего первоначальное назначение $_[0]->[0] означает что-то вроде: принимает первый аргумент функции тока ($_[0]), разыменования его (->) и рассмотрит это массив и возвращает его первое значение ([0]). Это значение не может быть списком или хешем, оно должно быть скаляром (строка, int, float, reference).

Вот несколько примеров:

my %hash = (MyKey => "MyValue"); 
my $hashref = \%hash; 
# The next line print all elements of %hash 
foreach (keys %hash) { print $_ } 
# And is equivalent to 
foreach (keys %{$hashref}) { print $_ } 
$hash{MyKey} == $hashref->{MyKey}; # is true 

Пожалуйста, обратитесь к http://perldoc.perl.org/perlreftut.html для получения более подробной информации.

+0

Нет, '$ _ [0]' не является функцией. Это первый (скалярный) элемент '@ _'. Итак, '$ _ [0] -> [0]' - это то же самое, что и '$ _ [0] [0]' и '$ {$ _ [0]} [0]' - принимает этот первый скалярный элемент '@ _', истолковывает его как ссылку на массив и возвращает первый элемент массива, предположительно связанного. – tchrist

+0

Никогда не говорил, что $ _ [0] является функцией. –

1

Предупреждение сообщает вам, что там ничего на $_[0]->[0]. Он не умирает и говорит вам, что вы ничего не индексируете, поэтому $_[0], скорее всего, является arrayref, но ничто не находится в первом слоте - или, возможно, оно указывает на пустой массив.

  • Если бы это была пустая строка или 0, она бы не пожаловалась.
  • Были там ссылки, вы могли бы напечатать что-нибудь, даже если: BLAH(0x80af74). (Где "BLAH" является одним из "ARRAY", "HASH", "SCALAR", "REF", "GLOB", "IO", ...)

Мое предложение состоит в том, что вы делаете это:

use Data::Dumper; 
say Data::Dumper->Dump([ $_[0] ]); # or even say Data::Dumper->Dump([ \@_ ]) 

, а затем посмотрите на выход.

После того, как вы получили hashref в $_[0]->[0], а затем, если необходимо перебрать хэша, лучший способ:

while (my ($key, $value) = each %$hashref) { 
    do_stuff_with_key_and_value($key, $value); 
} 

см each

Наконец, кажется, что у вас есть сигилу спутанность сознания. См. Последнюю часть этой ссылки для достойной попытки объяснить, что сигилы ('$', '@', '%'): не часть имени переменной, но указывает на то, что мы хотим получить от нее. Perl compilation woes