2011-08-20 67 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)关于它的一些问题。 –