2011-03-30 174 views
1

我想创建一个哈希数组,我想知道如何引用数组中的每个哈希?Perl的哈希数组 - 引用数组中的每个哈希值?

对于如:

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";  
} 

预先感谢任何帮助。

+0

在这个逻辑是比一个解决哈希和数组的使用有点更多的破碎。也许你可以解释你想要达到的目标,并且我们可以指出你朝着正确的方向。 – chambwez 2011-03-30 21:34:01

+0

http://perlmonks.org/?node=References+quick+reference可以非常有帮助 – ysth 2011-03-30 23:05:42

回答

3

你不需要

my @total =(); 

此:

my @total; 

够你用的是什么了。没有特别的语法需要声明你的数组将包含散列。

有做foreach部分的可能不同的方式,但这应该工作:

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

[BTW,宣布my @total;这个循环里面可能不是你想要的东西(它会在每行复位)。 。将第一循环外]

而且use strict; use warnings;,显然:-)

+0

你应该总是初始化你的变量。虽然它不再这样做,但Apache会重新启动一个mod_perl CGI,而不会将数据空间重置为零。这意味着之前的任何价值都被重新使用。程序防御性:始终初始化变量。 – shawnhcorey 2011-03-30 22:48:39

+0

@shawnhcorey:不,防守编程:使用词法(“my”)变量并在尽可能小的范围内声明它们。如果不使用全局变量(或范围是整个程序的词法),数据空间是否被清零并不重要,因为变量的值在超出范围时会丢失。 – 2011-03-31 10:22:36

+0

对不起,词法变量的作用范围是它们所在的区块,或者如果在区块之外,则区分它们所在的文件。它们不能从另一个文件访问,与'我们的'变量不同。 – shawnhcorey 2011-03-31 13:51:18

1

这里就是我得到:

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

我只是通过@total并为每个hashref采取片迭代按排序顺序并将这些值与选项卡连接。

如果没有需要他们以排序的顺序,你可以只

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

但我也将压缩行处理,像这样:

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

但随着List::MoreUtils,你也可以做到这一点:

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