Perl, A hash of arrays: adding and removing keys, adding to an array, all in a while loop

老子叫甜甜 提交于 2019-12-04 15:30:58

You can use what perl calls autovivification to make this quite easy. Your code doesn't need that central if-statement. You can boil it down to:

    push @{ $hash{$q} }, $seq;

If the particular key doesn't yet exist in the hash, perl will autoviv it, since it can infer that you wanted an array reference here.

You can find further resources on autovivification by Googling it. It's a unique enough word that the vast majority of the hits seem relevant. :-)

You are actually pretty close, a few notes though:

  1. In your else block you assign a reference to @q into your hash then immediately overwrite it with [$seq], only the last operation on the hash will hold

  2. You don't need next at the end of your loop, it will automatically go to the next iteration if there are no more statements to execute in the loop body.

Everything else seems to work fine, here are my revisions and the test data I used (since I don't know anything about DNA sequences I just used letters I remember from high school Biology)

Input file:

A 1
T 2
G 3 
A 3
A 2
G 5
C 1
C 1
C 2
T 4

Code:

use strict;
use warnings FATAL => 'all';

# open file for reading
open(my $fh, '<', 'test.txt');

my %hash;
while ( my $line = <$fh> ) { # read a line

    # split the line read from a file into a sequence name and value
    my ($q, $seq) = split(/\s+/, $line);

    if( exists $hash{$q} ) {
        push @{ $hash{$q} }, $seq;
    } 
    else {
        $hash{$q} = [$seq];
    }
}

# print the resulting hash
for my $k ( keys %hash ) {
   print "$k : ", join(', ', @{$hash{$k}}), "\n";
}


# prints
# A : 1, 3, 2
# T : 2, 4
# C : 1, 1, 2
# G : 3, 5
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!