在哈希值的末尾添加一个字符串

时间:2012-10-11 17:15:03

标签: perl

我是perl的新手,对使用哈希有疑问。虽然没有一个问题与我的问题有任何关系,但也提到了类似的问题。

我有一个fasta文件,其中包含几个不同长度的序列,并希望在每个fasta条目的末尾添加一个字符串(在本例中为N),直到所有序列的长度相同为止。此时,我能够读取fasta文件,并将每个序列作为字符串返回(但也可以作为数组)返回到散列值。关键元素是fasta文件的相应标题。

我的代码如下:

###### calculate the length of each hash value and store the highest value in $max
my $length;
my $max = 0;
my $addN = "N";

foreach $name ( keys %seq ) {
    $length = length($seq{$name});
    if ($max < $length) {
        $max = $length;
    } else { next }
    print $max,"\n";

    while (length ($seq{$name}) < $max) {
        $seq{$name} .= $addN;
    }
    foreach $name (keys %seq) {
        print $seq{$name};
        print "\n";
    }
}

这里的问题是这段代码的输出与输入完全相同,例如

INPUT:
>fasta1
AAAAAAAAA
>fasta2
AA
OUTPUT
>fasta1
AAAAAAAAA
>fasta2
AA

我想要这样的输出:

>fasta1
AAAAAAAAA
>fasta2
AANNNNNNN

你能帮我完成这项任务吗?

2 个答案:

答案 0 :(得分:2)

use 5.014;
my %seq = ( fasta1 => 'AAA',
            fasta2 => 'AAAAAA',
            fasta3 => 'AAAAAAAAA',
          );

my $length = length((sort { length($a) < length($b) } values %seq)[0]);
for my $name ( keys %seq ) {
    $seq{$name} = $seq{$name} . ('N' x ($length - length($seq{$name})));
}

while (my($name, $val) = each %seq ) {
    say "$name: $val";
}

fasta2: AAAAAANNN
fasta3: AAAAAAAAA
fasta1: AAANNNNNN

答案 1 :(得分:1)

您的示例代码错误。但是,听起来你有办法根据&#34; fasta&#34;填充地图。文件。假设这是真的,我认为以下代码可以解决您的问题。

# Populate %seq from fasta file
%seq = (                                                         
    "fasta1"=> "AAAAAAAAA",                                      
    "fasta2" => "AAAA",                                          
    "fasta3" => "AA"                                             
);                                                               

my $FILL = "N";                                                  
my $normalized_length = 0;                                       

# If the normalized length = longest value                       
while( my ($k,$v) = each %seq) {                                 
    my $len = length($v);                                        
    $normalized_length = $len if $len > $normalized_length;      
}                                                                

while( my ($k,$v) = each %seq) {                                 
    print $v, $FILL x ($normalized_length - length($v)), "\n";   
} 

输出

AAAANNNNN
AANNNNNNN
AAAAAAAAA

如果你需要规范化到一个固定的长度,那么只需将$ normalized_length设置为该值并跳过第一个while循环。