开发者

How to create hash of array in Perl

I have a data like this

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

How can create the data structure that looks like this:

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%']};

This is my attempt, but fail:

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

}


Here's how I'd do it:

my %big;
my $currentGroup;

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

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

You should probably add some additional error checking to this, e.g. an else clause to warn about lines that don't match either regex. Also, check to see if $currentGroup is undef before pushing (in case the first line begins with a tab instead of "Group").

The biggest problem with your original code is that you're declaring and initializing $head and @temp inside the loop, which means they got reset on every line. Variables that need to persist across lines have to be declared outside the loop, as I've done with $currentGroup.

I'm not quite sure what you're intending to accomplish with the s/[\r\s]+//g; bit. \r is included in \s, so that means the same as s/\s+//g; (which would strip all whitespace), but your desired result hash includes whitespace in your keys. If you want to strip trailing whitespace, you need to include an anchor: s/\s+\z//.


Well, I don't want to give you an answer, so I'll just tell you to look at:

  • perlref
  • perlreftut

Well, there ya go :-).


Your pushing arrays to your hash item. You should just be pushing the values. (You don't need @temp at all.)

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

Also $head must be declared outside your loop, otherwise it looses its value after each iteration.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜