[英]Perl: For loop exit condition (last) not working as expected
所以我下面的第二个for循环有问题。
第一个for循环在ARRAY中找到ATG的第一个实例。
第二个for循环应该报告第一个ATG之后的ARRAY中的TAA,TAG或TGA的第一个实例。 但是,它会报告阵列中最后一个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 \n@_ \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++;
}
问题是if ( ( defined $rf0_end ) > $rf0_start )
在第二个循环中if ( ( defined $rf0_end ) > $rf0_start )
。 它将布尔值与整数值进行比较。 为了正常工作,可以将其替换为
工作语法: if ( ( defined $rf0_end ) && ($rf0_end > $rf0_start) )
你也有问题
if ( defined( $rf0_end and $rf0_start ) ) {
需要
if ( defined $rf0_end and defined $rf0_start ) {
尽管在这种情况下
if ( defined $rf0_end ) {
会做得很好,因为$rf0_end
如果只获取定义$rf0_start
定义。
我宁愿使用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\n@_\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\n@_\nhas length: $rf0_len\n";
}
else {
print "No ORF found in @_\n";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.