I'm fairly new to Perl, so forgive me if this seems like a simple question...
Anyway, I have a hash of arrays and I'm trying to retrieve one of the arrays in the hash, but all I can get is the scalar size of the array.
%HoA = a hash of arrays
$key = some key in the hash
foreach $nextItem (@HoA{$key}) {
do a bunch of stuff with $nextItem
}
When I do this, $nextItem is always just the size of the array and the loop only runs through one time. I've tried printing the following:
@HoA{$key}
$HoA{$key}
@$HoA{$key}
The first two give me the scalar size and the third gives me nothing...what am I missing here?
UPDATE: I'm wondering if my problem is actually the way I'm adding the arrays to the hash. Here's what I'm doing:
@HoA{$key} = split(/ /, $list);
Does that stick the array in the hash, or the array size in the hash?
UPDATE 2: I tried the following block of code:
my $key = "TEST";
my %HoA = ();
my @testarray = (1, 2, 3);
@HoA{$key} = @testarray;
print Dumper(%HoA);
Here's the output:
$VAR1 = 'TEST';
$VAR2 = 1;
Why is it only sticking the first value of the array in?
Try referencing your array this way:
%HoA = a hash of arrays
$key = some key in the hash
foreach $nextItem (@{$HoA{$key}}) {
do a bunch of stuff with $nextItem
}
You take the array reference at $HoA{$key}
and make it an array.
Edit: For your update, I think you will get what you want, if you do it this way:
@{$HoA{$key}} = split(/ /, $list);
or you can do
push(@{$HoA{$key}}, split(/ /, $list);
For example:
my $list = "fred joe brown sam";
my %HoA = ();
my $key = "jacob";
@{$HoA{$key} = split(/ /, $list);
foreach my $item (@{$HoA{$key}})
{
print "Test item: $nextItem\n";
}
You will get:
Test item: fred
Test item: joe
Test item: brown
Test item: sam
Edit:
Add use strict;
to the top of your program. Basically you are attempting to use HoA as an array when you have a hash defined. You are referencing the contents of your hash improperly. To do it properly you really really need to have a $
between the @
and HoA
. Perl is typeless and will let you get away with murder if you don't use strict;
. A reference excerpt from oreilly might clear a few things up.
my @testarray
is an array my %hash
is a hash $hash{$el1} = \@array
is a hash element that has the value of a ref to an array@{$hash{$el1}} = @array
is a hash element that contains an array
Each entry in your hash is a reference to an array. For example:
$my_hash{$key}
is a reference to an array and not an array. $my_hash{$key}
is merely pointing to an area in memory where that array lives. To dereference it, you put the array symbol in front:
@{ my_hash{$key} }
Things get a bit hairier when we start talking about the elements:
${ my_hash{$key} }[0]
is the first element of that array. You can imagine if that array consisted of hashes to other arrays, the syntax can get quite obtrude. Fortunately, Perl has a clean way of handling it:
$my_hash{$key}->[0];
That's exactly the same as above, but easier to understand syntax. Sometimes, it's easier to use intermediate variables just so you can refer to things without all the dereferencing:
my %hash_of_array_refs;
foreach my $key (sort keys %hash_of_array_refs) {
my @array = @{ $hash_of_array_refs{$key} }; #Dereference
foreach my $element (@array) { #Much easier to read and understand
say "First element is $array[0]";
say "last element is $array[$#array]";
say "This element: $element";
}
}
Without dereferencing you get this:
my %hash_of_array_refs;
foreach my $key (sort keys %hash_of_array_refs) {
foreach my $element (@{ $hash_of_array_refs{$key} } ) { #Much easier to read and understand
say "First element is " . $hash_of_array_refs->[0];
say "last element is " . $hash_of_array_refs->[$#{ $hash_of_array_refs{key} } ]";
say "This element: $element";
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With