Почему я не могу помещать элементы в хэш массивов в Perl?

#arrays #perl #hash

Вопрос:

Я хочу, чтобы @{$allHash{$key1}}} был [«item1», «item2»].

Нажатие не работает, и все инструкции по печати предназначены для того, чтобы попытаться найти, куда отправились перемещенные элементы. Использование -> обозначения в push еще хуже, это заставляет $temp[0][0] и строку 24 отображать массив вместо элемента.

     #use strict;   # I've turned these off here to make the code easier to read
    #use warnings;

    my %allHash = ();
    my $key1 = "key1";
    my $item1 = "item1";
    my $item2 = "item2";
    #if (!exists($allHash{key1})) {$allHash{key1}=();}; # makes no difference, the array autovivefies anyway

    push (@{$allHash{$key1}},  $item1);         # push 1st item
    print"nnat11: pushed $key1, $item1";
    my @temp = $allHash{$key1};
    print"nat13:temp=@temp, length=",0 @temp, ", temp[0]=$temp[0], temp[0][0]=$temp[0][0]";
    print"nat14: allHash{$key1}[0]= $allHash{$key1}[0]";
    print"nat15: allHash{$key1}[1]= $allHash{$key1}[1]";
    print"nat16: allHash{$key1}[0][0]= $allHash{$key1}[0][0]";
    print"nat17: allHash{$key1}[1][0]= $allHash{$key1}[1][0]";
    print"nat18: allHash{$key1}[0][1]= $allHash{$key1}[0][1]n";
    print"n----------------";
    
    push (@{$allHash{$key1}},  $item2);         # push 2d item
    print"nnat21: pushed $key1, $item2";
    @temp = @{allHash{$key1}};
    print"nat23:temp=@temp, length=",0 @temp, ", temp[0]=$temp[0], temp[0][0] =$temp[0][0]";
    print"nat24: allHash{$key1}[0]= $allHash{$key1}[0]";
    print"nat25: allHash{$key1}[1]= $allHash{$key1}[1], allHash{$key1}[1][0] =$allHash{$key1}[1][0]";
    print"nat26: allHash{$key1}[0][0]= $allHash{$key1}[0][0]";
    print"nat27: allHash{$key1}[1][0]= $allHash{$key1}[1][0]";
    print"nat28: allHash{$key1}[0][1]= $allHash{$key1}[0][1]n";
 

Выводом из приведенной выше программы является:

 at11: pushed key1, item1
at13:temp=, length=1, temp[0]=ARRAY(0x331eb8), temp[0][0]=item1
at14: allHash{key1}[0]=item1
at15: allHash{key1}[1]=
at16: allHash{key1}[0][0]=
at17: allHash{key1}[1][0]=
at18: allHash{key1}[0][1]=

----------------

at21: pushed key1, item2
at23:temp=ARRAY(0x331ee8), length=1, temp[0]=ARRAY(0x331ee8), temp[0][0]=item1
at24: allHash{key1}[0]=item1
at25: allHash{key1}[1]= ARRAY(0x332020), allHash{key1}[1][0]=
at26: allHash{key1}[0][0]=
at27: allHash{key1}[1][0]=
at28: allHash{key1}[0][1]=
 

Странно то, что этот почти идентичный код из другой моей программы работает идеально.

 %hedgeHash = ();    # collect the members of each hedge as an array, using stub as key
for (my $i=0; $i<@options; $i  )
{   $Hstub = $options[$i][$iStub];
    push @{$hedgeHash{$Hstub}}, $i; # hedgehash should contain array of members of the hedge.
}
 

Что еще более странно, так это то, что если я удалю скобки из оператора push, я больше не получу «item1» в качестве вывода @temp и в строках 14 и 24, но получу другой массив! ВТФ??

Комментарии:

1. Код для добавления в эти массивы хорош и работает так, как должен. Это печать, которая неверна. Например: $allHash{$key1}[1][0] означало бы, что в хэше %allHash есть ключ $key1 (да, есть), у которого есть arrayref (да, есть), а у его второго элемента ( [1] ) есть … еще один массив! ( 0 попытка его индексирования) Нет, этого не может быть! В $allHash{$key1}[1] этом и есть ценность item2 . Так что печать вышла из-под контроля.

2. Я рекомендую время от времени распечатывать эти вещи, используя некоторые данные-«самосвал», и особенно когда что-то не так. Для этого есть ядро (установлено) Data::Dumper . Я использую Data::Dump (и его dd и pp ). Есть и другие, найдите свою любимую. Затем вы можете увидеть структуру данных, с которой играете, что может очень хорошо прояснить ваше видение 🙂

3. Извините, но #используйте строгие; # Я отключил их здесь, чтобы облегчить чтение кода ??? Не делай этого. Никогда так не делай.

4. Действительно, не делайте этого (отключите предупреждения/строгие); они нужны вам всегда-и особенно когда возникает проблема! Существуют предупреждения для тех ошибочных отпечатков, которые могли бы помочь.

Ответ №1:

Пожалуйста, ознакомьтесь с приведенным ниже примером кода, демонстрирующим использование хэша массивов.

Действительно, стиль кодирования OP несколько затрудняет чтение кода.

 use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my %allHash;
my $key1 = 'key1';
my $item1 = 'item1';
my $item2 = 'item2';
my $item3 = 'item3';
my $item4 = 'item4';
my $item5 = 'item5';

push @{$allHash{$key1}}, $item1;
push @{$allHash{$key1}}, $item2;

$allHash{$key1}[2] = $item3;
$allHash{$key1}[3] = [$item4,$item5];

say Dumper(%allHash);
 

Выход

 $VAR1 = {
          'key1' => [
                      'item1',
                      'item2',
                      'item3',
                      [
                        'item4',
                        'item5'
                      ]
                    ]
        };
 

Комментарии:

1. Спасибо! Ваш код работает нормально. Но то же самое относится и к первой фразе моей строки 25, которой раньше не было, и я не понимаю, почему. Но вы решили мою проблему, и, возможно, понимание придет позже.