2014-10-29 72 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"; 
    } 
}