Chris
Chris

Reputation: 3043

Perl Array of Hashes - Reference each hash within array?

I am trying to create an array of hashes, and I am wondering how to reference each hash within the array?

For eg:

while(<INFILE>)    
{    
  my $row = $_;    
  chomp $row;    
  my @cols = split(/\t/,$row);    
  my $key = $cols[0]."\t".$cols[1];     

  my @total = (); ## This is my array of hashes - wrong syntax???    

  for($i=2;$i<@cols;$i++)    
  {    
    $total[$c++]{$key} += $cols[$i];      
  }    
}

close INFILE;

foreach (sort keys %total)  #sort keys for one of the hashes within the array - wrong syntax???    
{    
  print $_."\t".$total[0]{$_}."\n";    
}

Thanks in advance for any help.

Upvotes: 1

Views: 6561

Answers (2)

Axeman
Axeman

Reputation: 29854

Here's what I get:

print join( "\t", @$_{ sort keys %$_ } ), "\n" foreach @total;

I'm simply iterating through @total and for each hashref taking a slice in sorted order and joining those values with tabs.

If you didn't need them in sorted order, you could just

print join( "\t", values %$_ ), "\n" foreach @total;

But I also would compress the line processing like so:

my ( $k1, $k2, @cols ) = split /\t/, $row;
my $key                = "$k1\t$k2";
$totals[ $_ ]{ $key } += $cols[ $_ ] foreach 0..$#cols;

But with List::MoreUtils, you could also do this:

use List::MoreUtils qw<pairwise>;
my ( $k1, $k2, @cols ) = split /\t/, $row;
my $key                = "$k1\t$k2";
pairwise { $a->{ $key } += $b } @totals => @cols;    

Upvotes: 1

Mat
Mat

Reputation: 206699

You don't need

my @total = ();

This:

my @total;

is sufficient for what you are after. No special syntax needed to declare that your array will contain hashes.

There's probably different ways of doing the foreach part, but this should work:

foreach (sort keys %{$total[$the_index_you_want]}) {
  print $_."\t".$total[$the_index_you_want]{$_}."\n";
}

[BTW, declaring my @total; inside that loop is probably not what you want (it would be reset on each line). Move that outside the first loop.]

And use strict; use warnings;, obviously :-)

Upvotes: 3

Related Questions