Home > Archive > PERL Beginners > August 2007 > Accessing hash within an array of hashes
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Accessing hash within an array of hashes
|
|
| Charles J Gillan 2007-08-07, 7:59 am |
|
I have a problem with extracting an individual hash from an array of
hashes. I can't work out, or find elsewhere, the syntax for this.
Code as follows:
devices_array_oH is set up as array of hashes
I want to loop over all hashes in the array and to print the key value pairs for
each hash.
I have tried the following but get run-time errors:
my($num_devices, $idevice);
$num_devices = scalar (@devices_array_oH) ;
for ($idevice=0; $idevice < $num_devices; $idevice++)
{
my (%device_hash, $itemp, $key);
$itemp = $idevice + 1;
#
#--- Extract one element of array to local hash
#
%device_hash = $devices_array_oH[$idevice]; <----------- Flagged as run-time error:
Reference found where even size list expected
print " Details of device $itemp: ";
print "\n\n";
foreach $key (keys(%device_hash))
{
print (" $key \t $device_hash{$key} \n"); <---- Flagged as run-time error
} use ofun-initialized value in concatenation
Presumably due to above
print "\n\n";
print " ***** End of details for all devices ";
print "\n\n";
}
Just can't figure it out - any suggestions.
Thanks,
Charles.
| |
| Paul Lalli 2007-08-07, 7:59 am |
| On Aug 7, 7:59 am, c.gil...@ecit.qub.ac.uk (Charles J Gillan) wrote:
> I have a problem with extracting an individual hash from an array of
> hashes. I can't work out, or find elsewhere, the syntax for this.
The syntax is found in
perldoc perlref
perldoc perlreftut
perldoc perllol
and
perldoc perldsc
> Code as follows:
>
> devices_array_oH is set up as array of hashes
No. There is no such variable. Variables in Perl start with $, @, %,
&, or *. Perhaps '@devices_array_oH' is an array of hashes?
> I want to loop over all hashes in the array and to print the key value pairs for
> each hash.
>
> I have tried the following but get run-time errors:
>
> my($num_devices, $idevice);
>
> $num_devices = scalar (@devices_array_oH) ;
> for ($idevice=0; $idevice < $num_devices; $idevice++)
These two lines are almost certainly better written:
for my $idevice (0 .. $#devices_array_oH) {
> {
> my (%device_hash, $itemp, $key);
>
> $itemp = $idevice + 1;
>
> #
> #--- Extract one element of array to local hash
> #
>
> %device_hash = $devices_array_oH[$idevice];
> <----------- Flagged as run-time error:
No. Flagged as run-time warning. Very different.
> Reference found where even size list expected
And did you look up that warning message to see what it means?
perldoc perldiag
Reference found where even-sized list expected
(W misc) You gave a single reference where Perl was
expecting a list with an even number of elements (for
assignment to a hash).
So this is telling you that $devices_array_oH[$idevice] is a
reference, and you're trying to use it as a hash. You can't do that.
You can either assign that reference to a new scalar variable, or you
can dereference the reference and assign the resulting hash to a hash
variable:
my $device_hash_ref = $devices_array_oH[$idevice];
or
my %device_hash = %{$device_array_oH[$idevice]};
> print " Details of device $itemp: ";
> print "\n\n";
>
> foreach $key (keys(%device_hash))
> {
> print (" $key \t $device_hash{$key} \n");
> <---- Flagged as run-time error
Again. Warning. Not Error. Errors cause your program to stop.
Warnings are Perl's way of telling you "this is probably not what you
meant to do."
> use of un-initialized value in concatenation
> Presumably due to above
Yes. Because you created a hash that has only one key-value pair.
The key is the stringified-form of that reference, and its value is
undef.
> }
>
> print "\n\n";
> print " ***** End of details for all devices ";
> print "\n\n";
> }
>
> Just can't figure it out - any suggestions.
I would have written the program like this:
my $itemp = 1;
foreach my $device_hash_ref (@devices_array_oH) {
print " Details of device $itemp: ";
print "\n\n";
foreach my $key (keys %{$device_hash_ref})
{
print (" $key \t $device_hash{$key} \n");
}
$itemp++;
}
There is rarely a need to use C-style for loops, or to access arrays
via indices. Just use a foreach loop and get access to their contents
(in this case, the references to hashes) directly.
Your main issue, I believe, is thinking that arrays can contain
hashes. They cannot. They can only contain *references* to hashes.
Therefore, when you get an element of one of these arrays, you get a
reference to a hash, not an actual hash. That reference must be
dereferenced in order to use it.
Please, do read those perldocs I referred you to earlier.
Paul Lalli
| |
| Mr. Shawn H. Corey 2007-08-07, 7:59 am |
| Paul Lalli wrote:
> I would have written the program like this:
>
> my $itemp = 1;
> foreach my $device_hash_ref (@devices_array_oH) {
>
> print " Details of device $itemp: ";
> print "\n\n";
>
> foreach my $key (keys %{$device_hash_ref})
> {
> print (" $key \t $device_hash{$key} \n");
print (" $key \t $device_hash_ref->{$key} \n");
> }
> $itemp++;
> }
>
--
Just my 0.00000002 million dollars worth,
Shawn
"For the things we have to learn before we can do them, we learn by doing them."
Aristotle
| |
| Paul Lalli 2007-08-07, 7:00 pm |
| On Aug 7, 8:29 am, shawnhco...@magma.ca (Mr. Shawn H. Corey) wrote:
> Paul Lalli wrote:
> print (" $key \t $device_hash_ref->{$key} \n");
Whoops! Quite correct. Thanks for catching that, Shawn.
Paul Lalli
|
|
|
|
|