2011-08-20 68 views
1

我有這樣如何創建數組的哈希在Perl

Group AT1G01040-TAIR-G 
     LOC_Os03g02970 69% 
Group AT1G01050-TAIR-G 
     LOC_Os10g26600 85% 
     LOC_Os10g26633 35% 
Group AT1G01090-TAIR-G 
     LOC_Os04g02900 74% 

數據如何創建的數據結構,看起來像這樣:

print Dumper \%big; 

$VAR = { "Group AT1G01040-TAIR-G" => ['LOC_Os03g02970 69%'], 
     "Group AT1G01050-TAIR-G" => ['LOC_Os10g26600 85%','LOC_Os10g26633 35%'], 
     "Group AT1G01090-TAIR-G" => ['LOC_Os04g02900 74%']}; 

這是我的嘗試,但失敗:

my %big; 
while (<>) { 
    chomp; 
    my $line = $_; 
    my $head = ""; 
    my @temp; 

    if ($line =~ /^Group/) { 
     $head = $line; 
     $head =~ s/[\r\s]+//g; 
     @temp =(); 


    } 
    elsif ($line =~ /^\t/){ 
     my $cont = $line; 
      $cont =~ s/[\t\r]+//g; 
     push @temp, $cont; 

     push @{$big{$head}},@temp; 
    }; 

} 
+1

爲什麼不產生哈希數組哈希?所以你的數據結構就像:'AT1G01040-TAIR-G'=> [{'LOC_Os03g02970'=> 69}](如果你需要對它們進行一些計算,或者將它們存儲在xml或...中? ) –

回答

2

以下是我會做:

my %big; 
my $currentGroup; 

while (my $line = <>) { 
    chomp $line; 

    if ($line =~ /^Group/) { 
     $big{$line} = $currentGroup = []; 
    } 
    elsif ($line =~ s/^\t+//) { 
     push @$currentGroup, $line; 
    } 
} 

很可能需要添加一些額外的錯誤檢查到這一點,例如一個else子句來警告關於不符合任何正則表達式的行。另外,請在推送前檢查$currentGroup是否爲undef(如果第一行以選項卡而不是「Group」開頭)。

與你原來的代碼最大的問題是,你聲明和初始化$head@temp循環,這意味着他們得到了在每一行復位。需要在線路上保持的變量必須在循環外部聲明,正如我在$currentGroup中所做的那樣。

我不太清楚你打算用s/[\r\s]+//g;位完成什麼。 \r包含在\s中,所以這意味着與s/\s+//g;(它將去除所有空格)相同,但是您希望的結果散列包含鍵中的空格。如果你想去掉尾隨的空白,你需要包含一個錨:s/\s+\z//

+0

我想我會做同樣的事情,但也請參考%big。('$ big - > {$ }}這讓我的Perl大師們花了很多時間來教/打敗我,直到我明白他們,但他們不能再活下去,我現在試圖說服我現在的同事們。 –

1

您將數組推送到您的哈希項目。你應該推動價值。 (你不需要@temp在所有。)

push @{$big{$head}}, $cont; 

而且$head必須在環之外聲明,否則每次迭代之後失去其價值。

+0

謝謝,但仍然無法正常工作 – neversaint

+1

你的意思是「不起作用」是什麼意思? – Mat

2

好了,我不想給你一個答案,所以我就告訴你看看:

嗯,有雅去:-)。

+2

perlreftut +1,最有用的docs in perldoc! –

+0

Thanks @Joel。我發現它在學習Perl中使用引用時非常有用 – Dynamic

+0

該評論讓我想起了我最喜歡的perldocs,並且做了一點[博客文章](http:// joelslinux .blogspot.com/2011/08/learning-perl-from-perldoc.html)關於它的一些問題。 –