2011-03-30 172 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;