繁体   English   中英

Perl:对于循环退出条件(最后)未按预期工作

[英]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::MoreUtilsfirstidx函数来执行此操作,如下所示,尽管您可能需要安装模块,因为它目前不在核心中。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM