遇到新值时,相同的值增量计数器重新开始

时间:2017-09-20 10:30:38

标签: perl counter

我有这个数组:

AAA
AAA
AAA
BBB
BBB
BBB

我想要做的是让一个计数器在遇到相同的值时递增,但在遇到新值时返回到1。那么输出就是:

AAA 1
AAA 2
AAA 3
BBB 1
BBB 2
BBB 3

我目前有这个代码,但它只是一直变为1并且不会增加并在遇到新值时返回到1。

sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}

my %fields = ( ID => 0, );

while ( my $line = <$inputFH> ) {

    chomp( $line );
    my @lineVal = split( ',', $line, -1 );

    #push all IDs to array
    push @IDs, $lineVal[ $SMfields{ID} ];

    #get unique IDs
    @uniqueID = uniq( @IDs );

    ###  PART WHERE I DO THE COUNTER ######
    foreach my $uID ( @uniqueID ) {
        my $row = 0
        if ( $lineVals[ $SMfields{SYMBOL} ] = $uID ) {
            $row++;
        }
    }

2 个答案:

答案 0 :(得分:3)

您还没有显示足够的代码,以便能够确定错误。该程序通过跟踪前一行的内容并在每次读取后进行比较以查看是否已更改来生成所需的输出

use strict;
use warnings 'all';

my $tag   = '';
my $count;

while ( my $line = <DATA> ) {
    chomp $line;
    $count = $tag ne $line ? 1 : $count + 1;
    print "$line $count\n";
    $tag = $line;
}

__DATA__
AAA
AAA
AAA
BBB
BBB
BBB

输出

AAA 1
AAA 2
AAA 3
BBB 1
BBB 2
BBB 3

答案 1 :(得分:0)

似乎是比awl更好的awk候选者,但关键的技巧是记住最后一个值并在当前值不等于最后一个值时重置计数器?

#!/bin/perl
while (<>) {
  chomp;
  if ($_ ne $last) {
    $last=$_;
    $ctr=1;
  } else {
    $ctr++;
  }
  print "$_ $ctr\n";
}

给出了:

$perl t.pl < a
AAA 1
AAA 2
AAA 3
BBB 1
BBB 2
BBB 3