How do I print unique elements in Perl array?

Question!

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;
$i=0;
while ($i != $faculty_len)
{
    	printf $fh '"'.$faculty[$i].'"';
    	$i++;
}


Answers

If you need to process the faculty list in any way, a map over the array converted to a hash for key coalescing and then sorting keys is another good way:

my @deduped = sort keys %{{ map { /.*/? ($_,1):() } @faculty }};
print join("\n", @deduped)."\n";

You process the list by changing the /.*/ regex for selecting or parsing and capturing accordingly, and you can output one or more mutated, non-unique keys per pass by making ($_,1):() arbitrarily complex.

If you need to modify the data in-flight with a substitution regex, say to remove dots from the names (s/\.//g), then a substitution according to the above pattern will mutate the original @faculty array due to $_ aliasing. You can get around $_ aliasing by making an anonymous copy of the @faculty array (see the so-called "baby cart" operator):

my @deduped = sort keys %{{ map {/.*/? do{s/\.//g; ($_,1)}:()} @{[ @faculty ]} }};
print join("\n", @deduped)."\n";
print "Unmolested array:\n".join("\n", @faculty)."\n";

In more recent versions of Perl, you can pass keys a hashref, and you can use the non-destructive substitution:

my @deduped = sort keys { map { /.*/? (s/\.//gr,1):() } @faculty };

Otherwise, the grep or $seen[$_]++ solutions elsewhere may be preferable.

By : derekm


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

my %hash;
@hash{@faculty}=1;
my @unique=keys %hash;

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

@_{@faculty}=1;
my @unique=keys %_;
By : psxls


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

By : jmmeier


This video can help you solving your question :)
By: admin