Perl Hash of Arrays of Arrays - PullRequest
       23

Perl Hash of Arrays of Arrays

1 голос
/ 22 февраля 2011

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

for my $y (0..$last_row - 2) {
    my $mlid = $Sheet->Cells($y+2, 1)->{'Value'}; 
    my @a = ();
    $a[0] = $Sheet->Cells($y+2, 3)->{'Value'}; 
    $a[1] = $Sheet->Cells($y+2, 4)->{'Value'}; 
    $a[2] = $Sheet->Cells($y+2, 6)->{'Value'}; 
    $a[3] = $Sheet->Cells($y+2, 7)->{'Value'}; 
    $a[4] = $Sheet->Cells($y+2, 8)->{'Value'}; 
    push @{$longHash{$mlid}}, [ @a ];
    print "Item in Array in Hash: $longHash{$mlid}[1][0]\n"; #this prints nothing

    if (exists $numPeople{$mlid}){
        $numPeople{$mlid}++;
    }else{
        $numPeople{$mlid} = 0;
        $numPeople{$mlid}++;
    }
}

print "Item in Array in Hash: $longHash{7202}[0][0]\n"; #this prints properly
print "Item in Array in Hash: $longHash{7202}[1][0]\n"; #this prints nothing

Поведение ДОЛЖНО быть:

У меня есть хэш. Ключ для одного mlid дает массив (представляющий человека). В каждом массиве должен быть другой массив, в котором индексы 0-4 определены из файла Excel, который я читаю.

Итак, чтобы получить данные из mlid 7202, от 7-го лица и 4-го столбца в Excel, я должен поместить $ longHash {7202} [7] [1] (потому что я сопоставил 4-й столбец с 1-м значение массива.)

Ответы [ 2 ]

4 голосов
/ 22 февраля 2011

Вы перезаписываете $longHash{$mlid} на каждой итерации цикла, поэтому в лучшем случае $longHash{7202}[$x] будет определено только для одного значения $x.

Если вы не делаете что-то более сложное, чем то, что вы показываете здесь, я не думаю, что вам вообще нужно очищать $longHash{$mlid}.Сказать, что

$longHash{key}[index] = expression

автоматически оживит $longHash{key} и $longhash{key}[index] без необходимости какой-либо предварительной инициализации.

($longHash{$mlid} = () также выглядит немного странно - выприсвоение пустого списка скалярной переменной. Я не думаю, что это отличается от высказывания $longHash{$mlid}=0. Если вы хотели установить для него пустую ссылку на массив, то вам следует использовать [] вместо ()).

2 голосов
/ 22 февраля 2011

Я вижу две проблемы.

  1. $longHash{$mlid} = ()

Вы пытаетесь установить скалярное поле в список. {$ mlid} `должен быть установлен в список ref , а не в список. Самое простое исправление - $longHash{$mlid} = [], но это не решит реальную проблему.

2. $longHash{$mlid}[$y] = [ @a ]; в сочетании с $longHash{$mlid} = ();

Вы очищаете $longHash{$mlid} на каждом проходе через цикл, затем пытаетесь присвоить ненулевой индекс. Может быть, вам нужен хеш хеша, а не список.

UPDATE

В твоей новой версии я думаю

push @{$longHash{$mlid}}, [ @a ];

должно быть просто

$longHash{$mlid} = [ @a ];

ОБНОВЛЕНИЕ 2

Я думаю, ваш код должен работать.

Это похоже на мой упрощенный пример ниже:

my %hash;

my @a;
$a[0] = "Fred";
$a[1] = 31;
$a[2] = "Melbourne";

push @{$hash{7202}}, [ @a ];

$a[0] = "Mary";
$a[1] = 25;
$a[2] = "Sydney";

push @{$hash{7202}}, [ @a ];

print $hash{7202}[0][0] . "\n";
print $hash{7202}[1][0] . "\n";

ОБНОВЛЕНИЕ 3

Пожалуйста, добавьте

use warnings;
use strict;

, чтобы гарантировать, что все индексы массива, которые вы считаете существующими, существуют.

И попробуйте перебрать ваши данные, чтобы напечатать их, например,

for my $mlid (keys %hash) {
    my $recordref = $hash{$mlid};
    my @record = @$recordref;
    for my $i (0..scalar(@record)-1) {
        printf "mlid %s person %d name %s\n", $mlid, $i, $record[$i][0];
    }
}
...