program - How do I print unique elements in Perl array?

perl remove duplicates from array of hashes (7)

I just found hackneyed 3 liner, enjoy

my %uniq; 
undef @uniq(@non_uniq_array); 
my @uniq_array = keys %uniq;

I'm pushing elements into an array during a while statement. Each element is a teacher's name. There ends up being duplicate teacher names in the array when the loop finishes. Sometimes they are not right next to each other in the array, sometimes they are.

How can I print only the unique values in that array after its finished getting values pushed into it? Without having to parse the entire array each time I want to print an element.

Heres the code after everything has been pushed into the array:

$faculty_len = @faculty;
while ($i != $faculty_len)
        printf $fh '"'.$faculty[$i].'"';

Answer #1

I suggest pushing it into a hash. like this:

my %faculty_hash = ();
foreach my $facs (@faculty) {
  $faculty_hash{$facs} = 1;
my @faculty_unique = keys(%faculty_hash);

Answer #2

Just another way to do it, useful only if you don't care about order:

my %hash;
my @unique=keys %hash;

If you want to avoid declaring a new variable, you can use the somehow underdocumented global variable %_

my @unique=keys %_;

Answer #3

Please note: Some of the answers containing a hash will change the ordering of the array. Hashes dont have any kind of order, so getting the keys or values will make a list with an undefined ordering.

This doen't apply to grep { ! $seen{$_}++ } @faculty

Answer #4

This question is answered with multiple solutions in perldoc. Just type at command line:

perldoc -q duplicate

Answer #5

Your best bet would be to use a (basically) built-in tool, like uniq (as described by innaM).

If you don't have the ability to use uniq and want to preserve order, you can use grep to simulate that.

my %seen;
my @unique = grep { ! $seen{$_}++ } @faculty;
# printing, etc.

This first gives you a hash where each key is each entry. Then, you iterate over each element, counting how many of them there are, and adding the first one. (Updated with comments by brian d foy)

Answer #6
use List::MoreUtils qw/ uniq /;
my @unique = uniq @faculty;
foreach ( @unique ) {
    print $_, "\n";