Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi
I have a for loop which is reading in values of the form Letter-Letter-Number e.g. AB1, BX6, WF2 etc
So lets say my loop runs for 10 iterations, and reads in the following -
AB1
BX6
WF2
CB7
EZ6
WY2
AB1
AB1
WF2
ET9

Now as you can see from the above - I have AB1 3 times, and WF2 2 times. I'm only interested in each unique value. Therefore how would I go about storing the values above in a unique manner, such as -
AB1
BX6
WF2
CB7
EZ6
WY2
ET9

I need to store these values in some kind of array, so I can output the unque values to a file, one the for loop has completed. If I didn't need unque value, I would simply pass them to the file as the loop executes.
THanks for your help.

Replies are listed 'Best First'.
Re: Storing unique values
by mirod (Canon) on Jan 18, 2003 at 18:36 UTC

    The "kind of array" you are looking for is called a hash:

    my %unique; while( <>) { chomp; $unique{$_}=1; } print join "\n", keys %unique;
Re: Storing unique values
by Aristotle (Chancellor) on Jan 18, 2003 at 20:06 UTC
    If you want to preserve the sequence in which you got them, just inserting in a hash won't do as the keys will come back in a pseudorandom order. In that case, you need something like this:
    #/usr/bin/perl -w use strict; my %seen; my @uniq = grep !$seen{$_}++, <>; print map "$_\n", @uniq;
    You can also look up counts by changing the last line to something like
    print map "$_: $seen{$_}\n", @uniq;

    Makeshifts last the longest.

Re: Storing unique values
by thezip (Vicar) on Jan 18, 2003 at 18:53 UTC
    This should do what you're looking for:
    #!/perl/bin/perl use warnings; use strict; my @arr = qw(AB1 BX6 WF2 CB7 EZ6 WY2 AB1 AB1 WF2 ET9); my $hash = {}; for my $cur (@arr) { if (exists($hash->{$cur})) { $hash->{$cur}++; } else { $hash->{$cur} = 1; } } my @unique = sort keys %$hash; for (@unique) { print sprintf qq(Value "%s" occurred %d times.\n), $_, $hash->{$_}; }

    As you parse through the source array, you can just check for existence in the %$hash, and then process/ignore as necessary.

    Where do you want *them* to go today?
      if (exists($hash->{$cur})) { $hash->{$cur}++; } else { $hash->{$cur} = 1; }
      No need to jump through hoops. Perl doesn't complain when increasing undefined variables, so this will do:
      $hash->{$cur}++;
      It's the accept practice for this case, in fact, so it should be done this way as well.

      Makeshifts last the longest.

Re: Storing unique values
by dr_jgbn (Beadle) on Jan 19, 2003 at 05:08 UTC
    I think this might work as is: let me know if not
    use strict;
    use vars qw ($outfile @array);
    open(DATA, $ARGV[0]) or die "Couldn't open $ARGV[0]: $!";
    $outfile = "testout.txt";
    open (OUT, ">$outfile") || die "Can't open $outfile for creation: $!\n";
    my (@array, %hash);
    while (<DATA>) {
    push (@array, $_) unless (defined($hash{$_}));
    $hash{$_} = 1;
    }
    print OUT join("", @array);
    Dr.J