http://www.perlmonks.org?node_id=962780

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear All,

I was using code that I found on PerlMonks page but can't seem to figure out how to use it. I have a set of hash reference created with;

$idx = 0; foreach $n (@IDs) { push @{$An{$n}->{b}} , $bb[$idx]; push @{$An{$n}->{c}} , $cc[$idx]; push @{$An{$n}->{e}} , $ee[$idx]; push @{$An{$n}->{d}} , $dd[$idx]; push @{$An{$n}->{f}} , $ff[$idx]; $idx++; }

How can I then for each $ID print values of corresponging position? Such as $ID[0], @{$An{$n}->{b}}[0]? etc. Btw is it a better practice to declare arguments with 'my' at the begining or just in code? I end up with a code ehader having declaration of 40+ variables (not always possible to do subs). Thanks for help.

Replies are listed 'Best First'.
Re: Print elements of hash references
by RichardK (Parson) on Mar 31, 2012 at 18:06 UTC

    Have a look at the perl data structures cookbook perldsc, it's a great intro to handling data.

    40 global variables sounds like a lot, perhaps a hash would be more suitable & easier to manage ? ( but without seeing the code it's difficult to tell)

      Thanks for that I will have a look. Can you tell me how to do it with this particular example? Those are (I think) array references and not array of arays or hash or arrays etc that the perldsc have.

        Looks like you have a hash of hashes of arrays of arrays. The principle is the same no matter how far you nest.

        push @{$An{$n}->{b}} , $bb[$idx];

        let's see, if perldsc did not make it clear enough, maybe perldata and perllol will help a bit further?
        Anyway, looking for "references" and Hashes of Hashes (HoH) and Hashes of Arrays (HoA) in the documentation and also on this site may help you along.

        What you are doing is pushing onto an array reference that is inside a hash (%An) of hashes the value in position ($idx) of an array (@bb).

        I am a little curious though: If you don't know what you are doing, why are you doing it?

        To see the results, do try use Data::Dumper;print Dumper \%An;

        Cheers, Sören

        where did $An get declared?

        Well, I don't really understand the code fragment you posted but, maybe

         print $An->{id}[0];

        Try using Data::Dumper to see the contents of $An

Re: Print elements of hash references
by stevieb (Canon) on Mar 31, 2012 at 18:40 UTC

    This is a hash of hash references that contain array references. (I think ;)

    To print them out, you have to dereference the entire structure as an array. See the full sample program below for further details on this dereferencing and accessing individual elements.

    say @{ $An{$id}->{b} };

    I couldn't find the original thread, so I have no idea what is in the lettered arrays, so I just threw something together as an example:

    #!/usr/bin/perl use warnings; use strict; use 5.10.0; my @bb = ( 41..60 ); my @cc = ( 21..40 ); my @IDs = ( 1..20 ); my %An; my $idx = 0; foreach my $n (@IDs) { push @{$An{$n}->{b}} , $bb[$idx]; push @{$An{$n}->{c}} , $cc[$idx]; $idx++; } # $An{$id}->{b} is an array reference. # To access its elements, we must dereference it # by encompassing the data structure within the # array dereferencing operator: @{} # to iterate over the entire array reference # note the @{} block surrounding the data structure say map { $_, ' ' } @{ $An{1}->{b} }; # to print out a single element of the aref say @{ $An{1}->{b} }[0]; # to print out the zeroeth element contained # in the 'b' value of each %An ID key: for my $id ( @IDs ){ say @{ $An{ $id }->{ b } }[0]; }

    As for your other question, you should always declare your variables in the smallest scope possible... ie. as close to the block you are going to use them in, and where possible, within the block you'll use them in. Having a whole boatload of variables declared needlessly at the top of the program is both unsightly and makes for hard to follow code.

      Thanks for that, that did the trick. The reason I am using this method is because I am facing a problem which with my beginner knowledge in perl would take me ages to solve. The solution I found did all I wanted and the only thing I had to do to finish the code was to print the results. Anyway thanks guys for your input it's time to spend some time with perl tutorials.