2014-10-29 73 views
0

所以我有我的第二个循环下面的问题。Perl:For循环退出条件(最后)不按预期方式工作

第一个for循环在ARRAY中查找第一个ATG实例。

第二个for循环应该报告在第一个ATG之后的ARRAY中的第一个TAA,TAG或TGA实例。但相反,它报告了ARRAY中最后一个TAA,TAG或TGA的位置。我不知道为什么退出循环的条件并不能防止这个问题,也不知道如何解决这个问题。

任何提示将不胜感激。

my @test_srsrspsp = ("CCC", "ATG", "ATG", "CGC", "TAA", "TAG"); 

sub orf_length { 
    #index scalars 
    my $rf0_start; 
    my $rf0_end; 
    #index value counter 
    my $i = 0; 
    #finds first appearance of ATG in array 
    for (@_) { 
     $rf0_start = $i if $_ eq 'ATG'; 
     last if (defined $rf0_start); 
     $i++; 
    } 
    #only looks for TAG, TAA, or TGA if ATG was found first 
    if (defined $rf0_start) { 
     #reset counter 
     $i = 0; 
     #is supposed to return the index value of the first appearance of TAG, TAA, or TGA 
     #that has an index value larger than that of ATGs but instead returns the index value 
     #of the last TAA, TAG, or TGA 
     for (@_) { 
      $rf0_end = $i if $_ =~ /TA(G|A)|TGA/; 
      if ((defined $rf0_end) > $rf0_start) { 
       last; 
      } 
      $i++; 
     } 
    } 
    #reports positions of found values and the number length of the sequence between them 
    if (defined($rf0_end and $rf0_start)) { 
     my $length = ($rf0_end - $rf0_start + 1) * 3; 
     print "Start Codon after pos: $rf0_start \n"; 
     print "End Codon at pos: $rf0_end \n"; 
     print "First ORF of \[email protected]_ \nhas length: $length \n"; 
    } else { 
     print "No ORF found in @_\n"; 
    } 

} 

我也试过使用for循环的不同版本没有成功。

for (@_) { 
    $rf0_end = $i if $_ =~ /TA(G|A)|TGA/; 
    last if ((defined $rf0_end) > $rf0_start); 
    $i++; 
} 

回答

0

问题是if ((defined $rf0_end) > $rf0_start)在第二循环中。它将一个布尔值与整数值进行比较。为了正常工作,它可以与

工作被替换语法:if ((defined $rf0_end) && ($rf0_end > $rf0_start))

0

你也有一个问题,这就需要将

if (defined $rf0_end and defined $rf0_start) { 

虽然线

if (defined($rf0_end and $rf0_start)) { 

,在这种情况下,

if (defined $rf0_end) { 

会做得很好,因为只有在定义了$rf0_start时才会定义$rf0_end

我倾向于使用List::MoreUtils中的firstidx函数来执行此操作,如下所示,尽管您可能需要安装模块,因为它目前不在内核中。

use strict; 
use warnings; 

use List::MoreUtils 'firstidx'; 

my @test_srsrspsp = qw/ CCC ATG ATG CGC TAA TAG /; 

orf_length(@test_srsrspsp); 

sub orf_length { 

    my ($rf0_start, $rf0_end, $rf0_len); 

    $rf0_start = firstidx { /ATG/ } @_; 
    if (defined $rf0_start) { 
     my $offset = $rf0_start + 1; 
     $rf0_end = $offset + firstidx { /TA[GA]|TGA/ } @_[$offset .. $#_]; 
    } 

    if (defined $rf0_end) { 
     my $rf0_len = ($rf0_end - $rf0_start + 1) * 3; 
     print "Start Codon after pos: $rf0_start \n"; 
     print "End Codon at pos: $rf0_end \n"; 
     print "First ORF of\[email protected]_\nhas length: $rf0_len\n"; 
    } 
    else { 
     print "No ORF found in @_\n"; 
    } 
} 

输出

Start Codon after pos: 1 
End Codon at pos: 4 
First ORF of 
CCC ATG ATG CGC TAA TAG 
has length: 12 

更新

如果你希望避免的模块,你可以写这样的看法。功能完全相同。

sub orf_length { 

    my ($rf0_start, $rf0_end, $rf0_len); 

    my $i = 0; 
    for (@_) { 
     if (not defined $rf0_start) { 
      $rf0_start = $i if /ATG/; 
     } 
     elsif (/TA[GA]|TGA/) { 
      $rf0_end = $i; 
      last; 
     } 
     ++$i; 
    } 

    if (defined $rf0_end) { 
     my $rf0_len = ($rf0_end - $rf0_start + 1) * 3; 
     print "Start Codon after pos: $rf0_start \n"; 
     print "End Codon at pos: $rf0_end \n"; 
     print "First ORF of\[email protected]_\nhas length: $rf0_len\n"; 
    } 
    else { 
     print "No ORF found in @_\n"; 
    } 
}