Search code examples
arraysperlhashmultidimensional-arrayperl-data-structures

Perl Hash of Arrays of Arrays


I'm having some variables in my Hash of multidimensional arrays disappear as soon as I leave a for-loop. The variables are printed correctly one-by-one in the loop, but when I print any item outside of the loop, it is always empty except for the first item.

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

The behavior SHOULD be:

I have a hash. The key for a single mlid gives an array (representing a person). In each of the array, there should be another array, in which the 0-4 indexes are defined from an Excel file I'm reading.

So, to get the data from the mlid 7202, from the 7th person, and the 4th column in Excel, I should put $longHash{7202}[7][1] (because I mapped the 4th column to the 1th value of the array.)


Solution

  • You are overwriting $longHash{$mlid} in every iteration of the loop, so in the best case $longHash{7202}[$x] will only be defined for one value of $x.

    Unless you are doing something a lot more complicated than what you show here, I don't think you need to clear $longHash{$mlid} at all. Saying

    $longHash{key}[index] = expression
    

    will auto-vivify both $longHash{key} and $longhash{key}[index] without the need for any pre-initialization.

    ( $longHash{$mlid} = () also looks a little strange -- you are assigning an empty list to a scalar variable. I don't think it's any different from saying $longHash{$mlid}=0. If you meant to set it to an empty array reference, then you should use [] instead of ()).