2014-01-08 2 views
0

Я пытаюсь получить доступ к значениям хэша внутри массива. Пример:Значения доступа из Hash внутри массива

@worte = {}; 

for my $i (0 .. 4){ 
    my (%wortObj) = (Index => $i, Text => "Text$i"); 
    print "$wortObj{Index} $wortObj{Text}\n"; 
    push @worte, %wortObj; 
} 

foreach $wortObject (@worte){ 
    print "$wortObject{Index} $wortObject{Text}\n"; 
} 

Первый оператор печати работает и создает правильный вывод. Я бы хотел, чтобы второй оператор печати выдавал тот же результат. Но я получаю только несколько пустых строк. Что я делаю не так?

ответ

1

У Perl есть функция, называемая контекстом, который является либо абсолютно блестящим, либо невероятно раздражающим. Теперь происходит, что хеш-переменная, используемая в контексте списка , оценивает плоский список ключей и значений, например. %hash = (Index => 1, Text => "Text1") может произвести список по

'Text', 'Text1', 'Index', 1 

Каждый из этих элементов является то push редактор на массив. Существует также скалярный контекст, который говорит нам, сколько «ведер» в хеше используется. Но как мы можем нажимать хэш на массив?

У нас нет. По определенным причинам коллекция не может иметь другую коллекцию в качестве значения. Вместо этого мы должны использовать ссылку , которую мы можем получить с помощью оператора \ (ссылка похожа на указатель, но более безопасна). Мы можем нажать, что хэш-ссылку на массив:

push @worte, \%wortObj; 

Теперь, когда мы перебираем элементы в массиве, они не хэши - они являются ссылками на хэши. Поэтому перед доступом к полям в «hashref» мы должны сначала разыменовать их. Один из способов сделать это является использование оператора ->, и мы получаем:

for my $wortObj (@worte) { 
    print "$wortObj->{Index} $wortObj->{Text}\n"; 
} 

Для получения дополнительной информации о ссылках, начните с perlreftut, то, возможно, читали perlref, perldsc и perlootut.

+0

Thank you. Я подозревал, что у меня что-то не хватает. Я даже экспериментировал с использованием фигурных скобок - считая, что этого достаточно, чтобы сказать Perl использовать хеш-ссылку вместо этого. Ну, еще раз, спасибо. – Icarus

0

Ну есть несколько ошибок, из-за которых ваш код не работает

@worte = {}; 

выше строка определяет массив написал и сделать его первым элементом в качестве хэш Другой крупный. Который мы не хотим. Мы можем просто объявить массив @wrote

for my $i (0 .. 4){ 
    my (%wortObj) = (Index => $i, Text => "Text$i"); 
    print "$wortObj{Index} $wortObj{Text}\n"; 
    push @worte, %wortObj; 

выше линии пытается сохранить% wortobj хэш в контексте списка, который не возможно, мы должны хранить его в скалярной Другой крупный. Мы можем редактировать код как push @worte, \% wortObj;

} 

foreach $wortObject (@worte){ 
    print "$wortObject{Index} $wortObject{Text}\n"; 

Вышеприведенная строка попыталась напечатать из hashrefence, но первый оператор -> никогда не подразумевается. Мы можем отредактировать его как print "$ wortObject -> {Index} $ wortObject -> {Text} \ n";

+0

oops the same answer :) again – Gaurav

+0

У меня бы слишком много ответов. Спасибо. (У меня слишком мало репутации в +1 вам, извините за это) – Icarus

+0

Прохладный ..и я предлагаю вам отредактировать строку @worte = {}; так как это создаст пустой хеш, который может привести к ошибке в вашем цикле foreach, в котором указано неинтеллизированное значение. – Gaurav

Смежные вопросы