http://www.perlmonks.org?node_id=144651


in reply to Re: Return a Unique Array
in thread Return a Unique Array

this will fail under certain circumstances. for instance:

my @non_unique = qw/carpet car pet/; # fails on 'car' and 'pet' my @non_unique = ("bob and sue","bob"); # fails on space seperated wor +ds
i could go on, but i think you get the point. if you don't want to alter the order of the items, and you want to use some perl 5 magic, you can use a pseudo-hash. before i go on, i must say that pseudo-hashes are considered a failed experiment, and will most likely not be suppored in Perl 6. the example below is simply to provide some enlightenment as to how they work (which i like.)

check Returning A Pseudo-Hash in Array Context for a little discussion on pseudo-hashes
for an offsite explanation on pseudo-hashes, find the link on japhy's homepage, http://www.crusoe.net/~jeffp/
also, check the documentation: fields and the Pseudo-hashes section of perlref

#!/usr/local/bin/perl -w use strict; $|++; # array of non-unique words my @non_unique = ('bob and sue', 'bobcat', 'carpet', 'bob', 'car', 'ca +rpet'); # create empty pseudo-hash # hash key is unique word, hash value is array index, array value is + count my $ph = [{},]; for(@non_unique) { if(exists $ph->{$_}) # if word already in hash, { $ph->{$_}++; # increment word count } else # else { $ph->[0]{$_} = @$ph; # set hash key to last array index (end + of array) $ph->{$_}++; # increment word count to 1 # or in one line... (a little obfuscated) # $ph->[$ph->[0]{$_} = @$ph]++; } # or on one line... (a little more obfuscated - not recommended) # exists $ph->{$_} ? $ph->{$_}++ : $ph->[$ph->[0]{$_} = @$ph]++; } # or on one line... (even more obfuscated - really not recommended) # map{exists$ph->{$_}?$ph->{$_}++:$ph->[$ph->[0]{$_}=@$ph]++}@non_uniq +ue; # array of unique words, same order as non-unique words # (the extraction procedure looks a little messy) # it says, for the keys of the hash section of the pseudo-hash, # sort by the value, ascending my @unique = sort { $ph->[0]{$a} <=> $ph->[0]{$b} } keys %{$ph->[0]}; # pretty formatted output of unique array and word count format SortedWordsAndCountHeader = Words Count . format SortedWordsAndCount = @<<<<<<<<<<<<<<<<<< @>>>> $_, $ph->{$_} . $^ = "SortedWordsAndCountHeader"; $~ = "SortedWordsAndCount"; write for @unique;
this produces the output

Words Count bob and sue 1 bobcat 1 carpet 2 bob 1 car 1

~Particle