如何在Perl中创建数组的哈希

时间:2011-08-20 07:05:19

标签: arrays perl hash

我有这样的数据

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

}

3 个答案:

答案 0 :(得分: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(如果第一行以制表符开头而不是“组”)。

原始代码的最大问题是您在循环中声明并初始化<{1}}和$head ,这意味着它们已在每一行重置。需要在行之间保持变量的变量必须在循环外声明,就像我使用@temp一样。

我不太确定你打算用$currentGroup位来完成什么。 s/[\r\s]+//g;中包含\r,因此与\s(将删除所有空格)相同,但您所需的结果哈希包含密钥中的空格。如果要删除尾随空格,则需要包含锚:s/\s+//g;

答案 1 :(得分:2)

好吧,我不想给你答案,所以我只想告诉你看看:

嗯,你去了: - )。

答案 2 :(得分:1)

将阵列推送到哈希项目。你应该只是推动价值观。 (根本不需要@temp。)

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

同样$head必须在循环之外声明,否则在每次迭代后都会失去它的值。