Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Perl Array of Hashes

by abhay180 (Acolyte)
on Jul 24, 2009 at 13:06 UTC ( #782969=perlquestion: print w/ replies, xml ) Need Help??
abhay180 has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am trying to create an array of hashes in my code. The key value pairs are pretty repetetive...hence i thought i can generate them as a string and assign it the array. But this doesnt seem to work!
This is how the array should look like: $xentry[0] = {BUCK_0 => JUNK, BUCK_1 => JUNK, BUCK_2 => JUNK, BUCK_3 = +> JUNK} ; $xentry[1] = {BUCK_0 => JUNK, BUCK_1 => JUNK, BUCK_2 => JUNK, BUCK_3 = +> JUNK} ; So on....
############################################### For this i did the following:
$str=""; for(my $i=0; $j<100;$i+=1) { for(my $j=0; $j<4;$j+=1) { $str .= "BUCK"."_"."$j"." => "."JUNK".","; } #Removes the Comma at the end $str = substr($str,0,length($str)-1); #Appending flower braces. $str = "{".$str."}"; $xentry[$i] = $str; $str=""; }
Now if i try accessing "$xentry[0]->{BUCK_0}"...It doesnt seem to work. Can somebody let me know the right thing to do?

Comment on Perl Array of Hashes
Select or Download Code
Re: Perl Array of Hashes
by moritz (Cardinal) on Jul 24, 2009 at 13:11 UTC
    You're not creating a hash, but a string that looks like a hash to you.

    Try something along these lines:

    my @xentry; for (0..100) { my %h; for my $j (0..4) { $h{"BUCK_$j"} = 'JUNK'; } push @xentry, \%h; }

    Read perldata and perlreftut for more introductory material.

      That was indeed very quick. Thanks a lot. It works.
        Hi, I wanted to do little more here...
        my $k=0,$str=""; for(my $i=0; $i<4;$i+=1) { @entry=undef; for my $j (0..7) { $h{"BUCK_$j"} = $bucket[$k+$j]; push @entry,\%h; } $hash_table[$i] = { ENTRY => [@entry]}; $k+=8; } #end of for i for(my $i=0; $i<4;$i+=1) { print "ENTRY-0-BUCK-0::", $hash_table[$i]->{ENTRY}->{BUCK_0}, "\n"; }
        The print of "ENTRY-0-BUCK-0" doesnt work....what is that i am doing wrong here?

      ...and the short version:

      my @xentry; push @xentry, { map { ("BUCK_$_" => 'JUNK') } (0 .. 4) } for 0 .. 100;
Re: Perl Array of Hashes
by davido (Archbishop) on Jul 25, 2009 at 06:41 UTC

    Is it necessary to create "BUCK_1", "BUCK_2", etc? That seems like an array.

    Does "BUCK" ever become something else? What if the datastructure looked more like this:

    $xentry[0] = { BUCK => [ qw/JUNK JUNK JUNK JUNK/ ], TUBS => [ qw/THUMP THUMP THUMP THUMP/ ] };

    Then instead of $xentry[0]->{BUCK_1} it would be $xentry[0]->{BUCK}[1], for example. I believe that not trying to create in-fix indexes in a hash key, and instead, letting arrays do your work will prove to be less headaches in the longrun.


    Dave

      David, Thanks for ur suggestion. I wanted to make number of "BUCK_*" as programmable. With every run of prog i want to have either "4/8/16/.." BUCKs in each entry. In a nut shell i am trying to mimic one kind of hash-table implementation,with bucket,entries e.t.c . I need the number of entries and buckets to be configurable from command line. Hence this approach i guess. Any better way of doing it would help. Thanks Abhay
Re: Perl Array of Hashes
by stevemayes (Scribe) on Jul 25, 2009 at 11:13 UTC

    One thing that helped me when building / understanding hashes, arrays, hashes of hashes, arrays of arrays, etc, was Data::Dumper as in...

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

    This would have shown you the structure of your "array of hashes" immediately.

      Hello, Thnaks a ton for all ur suggestions. I wanted to do little more here...
      my $k=0,$str=""; for(my $i=0; $i<4;$i+=1) { @entry=undef; for my $j (0..7) { $h{"BUCK_$j"} = $bucket[$k+$j]; push @entry,\%h; } $hash_table[$i] = { ENTRY => [@entry]}; $k+=8; } #end of for i for(my $i=0; $i<4;$i+=1) { print "ENTRY-0-BUCK-0::", $hash_table[$i]->{ENTRY}->{BUCK_0}, "\n"; }
      The print of "ENTRY-0-BUCK-0" doesnt work....what is that i am doing wrong here?

        Did you use warnings and use strict when you ran the code?

        But that aside, you are doing some strange things:

        my $k=0,$str=""; for(my $i=0; $i<4;$i+=1) { @entry=undef; for my $j (0..7) { $h{"BUCK_$j"} = $bucket[$k+$j]; push @entry,\%h; }

        The loop above will add 8 identical references to %h to @entry.

        $hash_table[$i] = { ENTRY => [@entry]}; $k+=8; } #end of for i for(my $i=0; $i<4;$i+=1) { print "ENTRY-0-BUCK-0::", $hash_table[$i]->{ENTRY}->{BUCK_0}, "\n";

        You can't address $hash_table like that since it is an array of hash references containing just the key ENTRY (which is a warning sign) that has the value array reference containing hash references.

        }

        Did you try following the advice and tried Data::Dumper on, say, (updated) @hash_table?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://782969]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (14)
As of 2014-07-30 15:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (235 votes), past polls