Problem populating an array of hashes

N

Niall

The attached code is intended to populate a hash with 2 keys , each
data element of the has being an array of integers - ie
key1 -> [5, 8, 19]
key2 -> [10,25]

However I end up with each array being empty. Can someone point me at
what I doing wrong ? Is it because when I set up the anonymous array I
need to pass a refernce ? I tried
$rh_hoa->{$key} = \[];
but this gave me a 'Not an Array reference' error

Thanks

use strict;
use warnings;
use Data::Dumper;

##################################################
sub AddValueToHash
{
my($rh_hoa, $key, $value) = @_;

if( !exists ($rh_hoa->{$key} ) )
{
$rh_hoa->{$key} = [];
}
push @ {$rh_hoa->{$key}}, $value;
return;
}
################################################
my %hoa = ();
while (<DATA>)
{
chomp;
my ($key, $value) = split;
AddValueToHash(\%hoa, $key, $value);
}
foreach my $key (keys %hoa)
{
print Dumper $key;
print Dumper $hoa{key};
}
################################################
__END__
key1 5
key1 8
key2 10
key1 19
key2 25
 
P

Paul Lalli

Niall said:
The attached code is intended to populate a hash with 2 keys , each
data element of the has being an array of integers - ie
key1 -> [5, 8, 19]
key2 -> [10,25]
use strict;
use warnings;
Excellent!

use Data::Dumper;

##################################################
sub AddValueToHash
{
my($rh_hoa, $key, $value) = @_;

if( !exists ($rh_hoa->{$key} ) )
{
$rh_hoa->{$key} = [];
}
push @ {$rh_hoa->{$key}}, $value;
return;
}
################################################
my %hoa = ();
while (<DATA>)
{
chomp;
my ($key, $value) = split;
AddValueToHash(\%hoa, $key, $value);
}
foreach my $key (keys %hoa)
{
print Dumper $key;
print Dumper $hoa{key};
^^^^^^^

Do you see something missing there? You're trying to print out the
value of the hash at position 'key', rather than at position $key.

Rather than this loop, if you want to inspect the entire hash, just do
it at once:

print Dumper(\%hoa);
}
################################################
__END__
key1 5
key1 8
key2 10
key1 19
key2 25

THANK YOU for posting a short, complete, self-contained program that we
were able to run. Much obliged.

Paul Lalli
 
P

Paul Lalli

Niall said:
The attached code is intended to populate a hash with 2 keys , each
data element of the has being an array of integers - ie
key1 -> [5, 8, 19]
key2 -> [10,25]

A couple more thoughts, after I hastilly posted the answer to the
actual question you asked...
However I end up with each array being empty. Can someone point me at
what I doing wrong ? Is it because when I set up the anonymous array I
need to pass a refernce ? I tried
$rh_hoa->{$key} = \[];
but this gave me a 'Not an Array reference' error

No, the statement $rh_hoa->{$key} = []; *is* using a reference. [] is
a reference to an anonymous empty array. \[] would be a reference to a
reference to an anonymous empty array. The reason you would get "not
an array reference" using that is that you'd need to throw an extra
level of dereferencing in.

Using the \[] syntax above:
$rh_hoa ==> reference to a hash.
$rh_hoa->{$key} ==> reference to a reference to an array
${$rh_hoa->{$key}} ==> reference to an array
@{${$rh_hoa->{$key}}} ==> array.
use strict;
use warnings;
use Data::Dumper;

##################################################
sub AddValueToHash
{
my($rh_hoa, $key, $value) = @_;

if( !exists ($rh_hoa->{$key} ) )
{
$rh_hoa->{$key} = [];
}

This entire if block is unnecessary. If the position in the hash does
not exist when Perl encounters this statement:
push @ {$rh_hoa->{$key}}, $value;

$rh_hoa->{$key} will automatically become an anonymous array reference.
This is known as "auto-vivification".
return;
}
################################################
my %hoa = ();
^^^^

This initialization is also unnecessary. An empty list is the default
value for a newly created hash.


Hope this helps,
Paul Lalli
 
N

Niall

All of that definitely does help Paul - thanks very much.

The reason I dumped $hoa{key} in a loop rather than the entire hash is
because in my real code (the code posted was just a minimkal test case)
I need to traverse the hash in a foreach loop and I wanted to verify
that this test gave me what I required.

I will try out the changes you recommend.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top