Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
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 imbibing at the Monastery: (12)
As of 2014-09-19 20:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (145 votes), past polls