shane1717
shane1717

Reputation: 97

Same value increment counter start over again when a new value is encountered

I have this array:

AAA
AAA
AAA
BBB
BBB
BBB

What I want to do is have a counter that increments if encountered a same value but goes back to 1 when a new value is encountered. So the output would then be:

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

I currently have this code, but it just goes 1 all the way and does not increment and go back to 1 when a new value is encountered.

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++;
        }
    }

Upvotes: 0

Views: 103

Answers (2)

Ian McGowan
Ian McGowan

Reputation: 3801

Seems like a better candidate for awk than perl, but the key trick is to remember the last value and reset the counter when the current value doesn't equal the last value?

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

Which gives:

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

Upvotes: 0

Borodin
Borodin

Reputation: 126722

You haven't shown enough of your code to be able to say for certain what is wrong. This program produces the output that you require by keeping track of the contents of the preceding line and comparing after each read to see if it has changed

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

output

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

Upvotes: 3

Related Questions