2017-01-19 3 views
0

Я столкнулся с препятствием в одном из своих сценариев perl, которые мне удалось решить, но я не совсем понимаю, почему он работает так, как он работает. Я прочесываю интернет, но я не нашел правильного объяснения.De-reference x количество раз для x количество структур данных

У меня есть подпрограмма, которая возвращает ссылку на хэш массивов. Хеш-ключи - это простые строки, а значения - ссылки на массивы.

я распечатать элементы массива, связанные с каждым ключом, как этот

for my $job_name (keys %$build_numbers) { 
    print "$job_name => "; 
    my @array = @{@$build_numbers{$job_name}}; # line 3 
    for my $item (@array) { 
     print "$item \n"; 
    } 
} 

В то время как я могу распечатать ключи & значения, я не очень понимаю, синтаксис за 3 строки.

Наша структура данных выглядит следующим образом:

Ссылка на хеш, значения которых являются ссылки на заселенных массивах.

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

Заключительный вопрос существо:

  • При работе с PERL хэш хэш массивов и т.д.; чтобы извлечь элементы в «дне» дерева данных соответствующей структуры данных, мы должны поочередно разыскивать каждый уровень, чтобы достичь исходных структур данных, пока мы не получим желаемый уровень элементов?

Надеюсь, кто-то может помочь, уточнив.

+1

Я не могу сказать, что представляет собой реальный вопрос, но ответ должен состоять в том, чтобы прочитать [perldsc] (http://perldoc.perl.org/perldsc.html) –

+1

Вывод из hashref, '$ build_numbers-> {$ job_name} ', затем разыщите это значение, так как это arrayref,' @ {$ build_numbers -> {$ job_name}} '. Вам нужны завитки в '@ {...}' для правил приоритета. Второй «@» в вашем коде является дополнительным. Это основы, есть много способов работать с ними. Да, вам нужно пройти уровни, чтобы добраться до дна, как еще? Вы должны прочитать соответствующие документы, после этого жизнь будет намного лучше. – zdim

+0

Является ли это синтаксический анализ какого-то рода? Обычно при создании синтаксического анализа XML или JSON вы получаете сложные структуры данных. – Sobrique

ответ

4

Линия 3 берет slice вашего хеш-справочника, но это очень странный способ сделать то, что вы пытаетесь сделать, потому что: a) вы обычно не срезаете ни одного элемента и b) есть более чистый и более очевидный синтаксис, который упростит чтение кода.

Если ваши данные выглядит примерно так:

my $data = { 
    foo => [0 .. 9], 
    bar => ['A' .. 'F'], 
}; 

Тогда правильная версия вашего примера будет:

for my $key (keys(%$data)) { 
    print "$key => "; 

    for my $val (@{$data->{$key}}) { 
     print "$val "; 
    } 

    print "\n"; 
} 

Который производит:

bar => A B C D E F 
foo => 0 1 2 3 4 5 6 7 8 9 

Если я понимаю ваш второй вопрос, ответ заключается в том, что вы можете получить доступ к точным местоположениям сложных структур данных, если вы используете правильный синтаксис. Например:

print "$data->{bar}->[4]\n"; 

Будет печать E.

Дополнительно рекомендуется чтение: perlref, perlreftut и perldsc

+0

Причина, по которой я это делал, заключается в том, что я не хотел использовать нотацию -> (как используется в вашем ответе и carlosns), но хотел использовать более короткую/более читаемую версию. Я думал, что @ $ hash_ref {$ job} эквивалентно @ {$ hash_ref -> {$ job}}. Но если я использую эту нотацию, моя печать возвращает шестнадцатеричный код для самого массива, а не его содержимое. Затем я попытался добавить еще один символ @ {}, чтобы снова открыть его, и на этот раз показалось, что он распечатывает содержимое массива. Ваш формат на самом деле более четкий, чем тот, который я нашел для работы. – sSmacKk

0

Работа со структурами данных может быть трудно в зависимости от того, как это было сделано.

Я не уверен, если ваша «работа» структура данных именно это, но:

#!/usr/bin/env perl 

use strict; 
use warnings; 
use diagnostics; 


my $hash_ref = { 

job_one => [ 'one', 'two'], 
job_two => [ '1','2'], 

}; 

foreach my $job (keys %{$hash_ref}){ 

print " Job => $job\n"; 

my @array = @{$hash_ref->{$job}}; 

foreach my $item (@array) 
{ 

     print "Job: $job Item $item\n"; 
} 

} 

У вас есть ссылка на хеш, который вы перебирать ключи, которые являются массивами. Но каждый элемент этого массива может быть другой ссылкой или простым скаляром.

В принципе, вы можете работать с ref или отменять рефери, как в первом цикле.

Имеется документация, которую вы можете проверить для получения более подробной информации. here.

Так, отвечая на ваш вопрос:

Заключительный вопрос являются: - Когда имеешь дело с PERL хэши хэшей массивов и т.д.; для извлечения элементов на «дне» соответствующего «дна» структуры данных «» мы должны разыменовывать каждый уровень, в свою очередь, до до исходных структур данных до тех пор, пока мы не получим нужный уровень элементов?

Это зависит от того, как была сделана ваша структура данных и, если вы уже знаете, что вы ищете это было бы просто, чтобы получить значение, например:

% city_codes = (

a => 1, b => 2,

);

my $ value = $ city_codes {a};

Комплексные структуры данных имеют сложный код.

+0

Я попробовал синтаксис, который вы предложили @ {$ hash_ref -> {$ job}}, чтобы создать мой массив, и он сработал. Хотя я видел, что этот синтаксис используется в документах, которые я использовал; Я попытался использовать более короткую версию, т.е. без -> и моя версия также работает. @ {@ $ Build_numbers {$ job_name}}. – sSmacKk

+0

Так что все хорошо :-) – carlosn

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