Arrays #7

#0 | #1 | #2 | #3 | #4 | #5 | #6 | #7

Unique Elements

A common task you may have to do is get a list of unique elements out of an array. Of course there's nothing illegal about having duplicate or identical elements in an array. But what if we just want the unique ones?

Here's a short list of cities with some duplicates thrown in. We just want the unique ones ...

my @foo=(
    "boston",
    "toronto",
    "ottawa",
    "quebec city",
    "windsor",
    "hamilton",
    "london",
    "boston",
    "ottawa",
    "quebec",
    "Quebec",
);

We use a new hash %seen, to save items that have been 'seen'. Then 'push' any unseen items into a new array @fooUniq.

my @fooUniq = ();
my %seen=();
foreach my $item (@foo) {
    unless ($seen{$item}) {
        $seen{$item} = 1;
        push (@fooUniq, $item);
    }
}
print "Unique #1: ...\n";
foreach my $item(sort @fooUniq) {
    print "$item\n";
}

Most of that should make sense except for the use of the unless modifier. It works like an if not, then do this.

Here we are checking if the %seen hash contains a key for the current $item. If NOT, then we set the key ($item) to the value 1. We also push $item into our array @fooUniq.

All that's left then is to print the (sorted) array:

OR ...

my %seen=();
foreach my $item (@foo) {
    $seen{$item}++;
}
@fooUniq = keys %seen;

Looping through @foo we increment %seen for that key ({$item}++). Outside the loop we set our new array @fooUniq to the keys of %seen, which are now unique.

Then print the new array ...

print "Unique #2: ...\n";
foreach (sort @fooUniq) {
    print "$_\n";
}

Note that 'Quebec' appears first in both sorted lists because of the uppercase 'Q'.