2014-12-31 8 views
0

Итак, я пытаюсь использовать Perl HoH и вставлять некоторые значения в массив из HoH.Perl Hash of Hash

Вот часть кода, чтобы лучше объяснить;

my $hoh = (
antenna_included=>{ 
    "1" => '1 MultiBand Antenna', 
    "2" =>'2 Multiband Antennas', 
    "3" =>'1 MultiBand Antenna & 2 WiFi Antennas', 
    "4" =>'2 Multiband Cellular Antennas & 2 WiFi Antennas', 
    "N" =>'No Antennas Included', 
    }, 
ip_rating=>{ 
    I6 => 'IP 64', 
    CD => 'Intrinsically Safe, Class 1 Div 2, IP 64', 
    NI => 'No', 
    }); 

foreach $group (sort keys %hoh) { 
    foreach $spec (sort keys %{ $hoh{$group} }) { 
     print "$spec=>$hoh{$group}{$spec}\n"; 
    } 

    print "what part is it: "; 
    my $input = <STDIN>; 
    chomp $input; 

    if (exists $hoh{$group}) { 
     print "$hoh{$spec}\n";    #this is the problematic line. 
    } 
    else { 
    print "not a match!\n"; 
    } 
} 

В основном цель этого сценария является проходным Хох, но и на протяжении каждого блока хэш дает STDIN, то введите в key, а затем я хочу, чтобы подтолкнуть value этого элемента в массив. (Сейчас код просто говорит print для отладки).

Я попытался

$hoh{$group}{$spec} 
$hoh{$group} 
$hoh{$group}->{$spec} 

Для $hoh{$group} я получаю HASH(0x6ff920) и все другие ценности оно просто пустой, без ошибок.

Любые мысли? Спасибо

ответ

2

Используйте оператора ->.

Все под HoH - это хэш ref, а для доступа к ним требуется оператор ->. (Технически, у вас есть «hash of hashref», а не «hash of hash», поскольку такая вещь невозможна.)

См. Документы perlref.

$hoh{$group}->{$spec} 

UPDATE

Вот модифицированная версия программы. Отличия:

  • Начальная декларация %hoh осуществляется с помощью хеш-переменной %hoh, а не скалярной переменной, $hoh. Присвоение списку инициализации $hoh приведет к тому, что последнему элементу списка присваивается переменная, в этом случае hashref, соответствующая ip_rating. Это почти наверняка не то, что вы хотите.
  • Для доступа к элементу $hoh{$group} требуется оператор ->, например `$ hoh {$ group} -> {$ spec}.
  • Проблемная область, вероятно, должна быть проверена на наличие $hoh{$group}->{$input}. Если он не существует, вход недействителен, что и предлагает сообщение.

Вам просто нужно понимать разницу между хэш и hashref (аналогично разнице между массивом и ссылкой на массив), и понимают, что хэши и массивы не могут быть элементами других хэшей или массивы. Hash ref s и array ref s могут быть элементами других структур данных, поскольку только одни скаляры могут содержаться в другой структуре данных. Хэши и массивы не являются скалярами, но ссылки являются скалярами (включая hashref, arrayrefs, coderefs и даже scalarrefs) и необходимы для создания любой сложной вложенной структуры данных.


my %hoh = (
    antenna_included=>{ 
     "1" => '1 MultiBand Antenna', 
     "2" =>'2 Multiband Antennas', 
     "3" =>'1 MultiBand Antenna & 2 WiFi Antennas', 
     "4" =>'2 Multiband Cellular Antennas & 2 WiFi Antennas', 
     "N" =>'No Antennas Included', 
    }, 
    ip_rating=>{ 
     I6 => 'IP 64', 
     CD => 'Intrinsically Safe, Class 1 Div 2, IP 64', 
     NI => 'No', 
    }); 

foreach $group (sort keys %hoh) { 
    foreach $spec (sort keys %{ $hoh{$group} }) { 
     print "$spec=>$hoh{$group}->{$spec}\n"; 
    } 

    print "what part is it: "; 
    my $input = <STDIN>; 
    chomp $input; 

    if (exists $hoh{$group}->{$input}) { 
     print $hoh{$group}->{$input}."\n"; 
    } 
    else { 
     print "not a match!\n"; 
    } 
} 
+0

Спасибо за ответа и ссылки. Это не работает (по крайней мере, просто добавляя это к одной «проблемной» линии). Как вы думаете, может быть, потому что мне нужно использовать оператор '->' в циклах 'for' выше, и тогда я смогу ссылаться на него? – nzaleski

1

Брекеты {...} и круглые скобки (...) очень Diffferent. Первый определяет анонимный хеш, который присваивается переменной скаляр, а второй определяет список, который вы бы присвоили переменной хэш-переменной. У вас есть смесь двух, и неясно, что вы имели в виду.

  • Если у вас есть скалярная переменная $hoh, то вам необходимо инициализировать его с

    my $hoh = { ... } 
    

    и доступ к элементам с косвенного оператора

    $hoh->{$group}->{$spec} 
    

    или

    $hoh->{$group}{$spec} 
    
  • Если у вас есть хэша переменных а, то вам необходимо инициализировать его с

    my %hoh = (...) 
    

    и доступом к элементам непосредственно

    $hoh{$group}->{$spec} 
    

    или

    $hoh{$group}{$spec} 
    
+1

@mojo: 'perl -E '% hoh = (G => {S => works}); ($ group, $ spec) = qw/G S /; скажем $ hoh {$ group} {$ spec} '' – Borodin

+0

Я стою исправлен. Я не понимаю, почему, если '$ hoh = {...}', вы не можете '$ hoh {$ key}', но если '$ hoh {$ key}' возвращает hashref, вы можете '$ hoh { $ key} {$ subkey} '* AND *' $ hoh {$ key} -> {$ subkey} 'с тем же результатом. – mojo

+2

@mojo: Поскольку стрелка направления является опцией * только между парами замыкающих/открывающих скобок '} {' или brackets '] [' *. В любом случае в противном случае не было бы различия между '$ hoh {$ key}', являющимся элементом '% hoh' и' $ hoh -> {$ key} ', являющимся элементом'% $ hoh'. – Borodin