如何在Perl中使用计数器生成数组?

时间:2012-04-04 23:03:52

标签: arrays perl while-loop unique counter

我想生成一个唯一 ID列表。由于某些ID是重复的,我需要在末尾添加一个数字以使其唯一,如下所示:

ID = exon00001
ID = exon00002
ID = exon00003
ID = exon00004

这是我到目前为止所拥有的。

 while (loop through the IDs) {
 # if $id is an exon, then increment the counter by one and add it 
 # to the end of the ID
    if ($id =~ m/exon/) {
    my $exon_count = 0;
    my @exon = $exon_count++; #3
    $number = pop @exon; # removes the first element of the list
    $id = $id.$number;
    print $id."/n"
    }
    }

基本上我想用计数器动态生成数组。它应该为外显子总数创建一个数组(1,2,3,4,...),然后删除元素并将其添加到字符串中。此代码无法正常运行。我认为第3行有问题。你们都知道吗?有任何想法吗?谢谢

3 个答案:

答案 0 :(得分:1)

正如我的评论中所述,您的代码无法编译,也无法正常工作。首先计算重复项,然后根据找到的ID打印正确的重复项计数。使用printf将适合格式化您的号码。

my %seen;
my @ids = ( bunch of ids );

map $seen{$_}++, @ids;  # count the duplicates

for my $id (keys %seen) {
    for my $num (1 .. $seen{$id}) {
        printf "%s%05d\n", $id, $num;
    }
}

答案 1 :(得分:1)

这是你需要的吗?计数器需要保留其值,因此您无法按原样重置它:

use v5.10;

my $exon_count = 0;
while( my $id = <DATA> ) {
    chomp $id;
    if( $id =~ m/exon/ ) {
        $id = sprintf "%s.%03d", $id, $exon_count++;
        }
    say $id;
    }

__END__
ID=exon00001
ID=exon00002
ID=exon00003
ID=exon00004

输出如下:

ID=exon00001.000
ID=exon00002.001
ID=exon00003.002
ID=exon00004.003

如果您使用的是5.10或更高版本,则可以使用state在循环中声明变量,但让它保持其值:

use v5.10;

while( my $id = <DATA> ) {
    chomp $id;
    state $exon_count = 0;
    if( $id =~ m/exon/ ) {
        $id = sprintf "%s.%03d", $id, $exon_count++;
        }
    say $id;
    }

我认为你是Perl的新手,因为你的代码看起来像是一些不相关的东西,可能与你认为的有很大不同。有一个针对生物学家的Perl教程,"Unix and Perl"。还有我的 Learning Perl 一书。

Joel问到使用字符串作为附加标签。没关系; Perl允许您increment a string,但仅限于a-zA-Z范围。我们可以通过在基数36中使用数字标记来混合数字和字母:

use v5.10;

use Math::Base36 'encode_base36';

while( my $id = <DATA> ) {
    chomp $id;
    state $exon_count = 30;
    if( $id =~ m/exon/ ) {
        $id = sprintf "%s.%-5s", $id, encode_base36($exon_count++);
        }
    say $id;
    }

现在你有这样的标签:

ID=exon00003.1Q   
ID=exon00004.1R   
ID=exon00001.1S   
ID=exon00002.1T   
ID=exon00003.1U   
ID=exon00004.1V   

答案 2 :(得分:0)

您想为这些外显子生成唯一ID的列表(输出到GFF文件中吗?)。

您必须确保在循环外部初始化计数器。我不确定你想要用数组完成什么。但是,下面的程序将根据您发布的格式(exon00001等)生成独特的外显子ID。

my $exon_count=0;

while(my $id=<SOMEINPUT>){
      if($id=~m/exon/){
            $exon_count++;
        my $num='0' x (5 - length $exon_count) . $exon_count;
            print "$id$num\n";
      }
}