Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Storing a Hash Made of Two Arrays in Another Hash

by BJ_Covert_Action (Beadle)
on Jan 10, 2012 at 17:40 UTC ( #947201=perlquestion: print w/replies, xml ) Need Help??

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

Howdy Monks,

So I've been bejiggering with this code for awhile and it's not working out the way I need it to. I am parsing a text file where the first line consists of headings that I would like to use for keys in a hash. The next few lines contain values. I'd like to store each line of values in a hash that is keyed by the headings in the first line, and contains the values in the second line. However, I'd like to store each of those hashes in a master hash that is keyed by the first value in each row. So the data I am looking at resembles the following:

Heading 1 Heading 2 Heading 3 ... Value A1 Value A2 Value A3 ... Value B1 Value B2 Value B3 ... . . .

I am trying to parse that code with the following subroutine (please note values are delimited by tabs, so the parsing is working as expected)

sub get_fields{ my $local_filein = shift; # Input file needs to be the first fi +le passed to get_fields my %tmp_hash; my %tickets; my @keys; my @values; while(my $line = <$local_filein>){ chomp $line; if ($line =~ m/^\D/){ @keys = split(/\t/, $line); }elsif($line =~ m/d/){ @values = split(/\t/, $line); @tmp_hash{@keys} = @values; # foreach(keys %tmp_hash){ # print "KEY: $_ VALUE: $tmp_hash{$_}\n" # } $tickets { $values[0] } = %tmp_hash; #$tickets{ @values[0]{@keys}} = @values; #$tickets{ $values[0] } = { each %tmp_hash }; # Each is a + piece of shit. Use @ context or something else. } } #@tickets{@keys} = @values; return %tickets; }

The line of code I am having trouble with is the one where I am trying to assign the values of %tmp_hash into the master hash %tickets. As you can see, I've tried a few different things which I've commented out. Basically, %tmp_hash is getting created just fine by assigning it the arrays @keys and @values. But I'd like to do something similar to make %tickets the hash of temporary hashes keyed by the first value in the @values array. I can't seem to get the context to work out.

Any help y'all could provide would be appreciated.


Replies are listed 'Best First'.
Re: Storing a Hash Made of Two Arrays in Another Hash
by tobyink (Canon) on Jan 10, 2012 at 18:01 UTC

    Something like this?

    use Modern::Perl; use Data::Dumper; my @field_names; my %master_hash; while (<DATA>) { chomp; if (1..1) { @field_names = split /\t/ and next; } my %this_hash; my @values = split /\t/; @this_hash{ @field_names } = @values; $master_hash{$values[0]} = \%this_hash; } print Dumper \%master_hash; __DATA__ Name Pet monkey John Biggles Steve Bubbles Henry Binky

    In your particular example, this line is wrong:

    $tickets { $values[0] } = %tmp_hash;

    You're trying to assign a hash into a scalar slot. You need to assign a reference to the hash instead:

    $tickets { $values[0] } = \%tmp_hash;

    See perldoc perlref and perldoc perllol.

      Perfect! Worked like a charm. Thanks toby!

      I knew it was something simple, but it's been awhile since I built complex data structures in perl and I'm dusting off the cobwebs still.
      Yeah, I knew which line was wrong. I didn't know how to make that line right. Let me try the reference. Thanks!
Re: Storing a Hash Made of Two Arrays in Another Hash
by toolic (Bishop) on Jan 10, 2012 at 17:59 UTC
    if ($line =~ m/^\D/){
    That matches every line of the input you have shown. The elsif clause is never entered. Therefore, we can not reproduce your results with your input data and code. See

      Yeah, the sample input I was giving was just a template. Here, try this:

      Heading1 Heading2 Heading3 100 200 300 400 500 600

      You're still going to have to replace those spaces with tab characters to make the parsing work on that though.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2020-10-24 04:04 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (242 votes). Check out past polls.