【问题标题】:Add a string to the end of hash values将字符串添加到哈希值的末尾
【发布时间】:2012-10-11 17:15:03
【问题描述】:

我是 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

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

【问题讨论】:

  • 您的代码在重新格式化后看起来完全错误。您在发布之前是否进行了简化导致这种错误嵌套?
  • 对我来说样本输入是如何被读入的并不明显——假设它以某种方式进入了 %seq 散列?如果您能解释一下,可能会有所帮助。

标签: perl


【解决方案1】:
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

【讨论】:

  • 大家好,非常感谢 Oesor 和 Sebastian,你们的代码对我来说都很好。现在我可以继续前进了!干杯
【解决方案2】:

您的示例代码有误。但是,听起来您有一种方法可以根据“fasta”文件填充地图。假设这是真的,我认为以下代码可以解决您的问题。

# 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 循环。

【讨论】:

  • 大家好,非常感谢 Oesor 和 Sebastian,你们的代码对我来说都很好。现在我可以继续前进了!干杯
猜你喜欢
  • 2023-03-29
  • 2012-08-03
  • 1970-01-01
  • 2016-09-06
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
相关资源
最近更新 更多