How to get rid of duplicate values in an array in Perl 6?
Basically we show various ways how one can take a list of values and return a sublist of the same values after eliminating the duplicates.
With Perl 6 its quite easy to eliminate duplicate values from a list as there is a built-in called unique that will do the job.
examples/unique_numbers.pl6
use v6; my @duplicates = 1, 1, 2, 5, 1, 4, 3, 2, 1; say @duplicates.perl; # [1, 1, 2, 5, 1, 4, 3, 2, 1] my @unique = unique @duplicates; say @unique.perl; # [1, 2, 5, 4, 3]
This works on strings as well:
examples/unique_strings.pl6
use v6.c; my @chars = qw/b c a d b a a a b/; say @chars.perl; # ["b", "c", "a", "d", "b", "a", "a", "a", "b"] my @singles = unique @chars; say @singles.perl; # ["b", "c", "a", "d"]
If you long for the behavior of the Unix uniq command that would only eliminate the consecutive duplicates then you might be happy to hear that Perl 6 has a function for you. It is called squish. (Learning Perl 6 has the advantage that you also learn new words in English :).
Anyway, here is an example:
examples/squish_strings.pl6
use v6.c; my @chars = qw/b c a d b a a a b/; say @chars.perl; # ["b", "c", "a", "d", "b", "a", "a", "a", "b"] my @sort-of-singles = squish @chars; say @sort-of-singles.perl; # ["b", "c", "a", "d", "b", "a", "b"]
There is however another slightly related tool called a Bag which is a method, that will count the number of occurrences of each element and create a Bag out of them.
examples/bag_strings.pl6
use v6.c; my @chars = qw/b c a d b a a a b/; say @chars.perl; # ["b", "c", "a", "d", "b", "a", "a", "a", "b"] my $count = @chars.Bag; say $count.^name; # Bag say $count.perl; # ("d"=>1,"b"=>3,"a"=>4,"c"=>1).Bag say $count<a>; # 4
A few comments to people new to Perl 6:
One should start every Perl 6 script by asking for v6; or v6.c; version 6 of Perl. It is important in order to avoid strange error messages when someone runs it with perl 5 by mistake.
You can add .perl to almost every kind of variable and get back a representation of the data in it. Very handy for debugging.
say() is a built-in function in Perl 6 similar to say() in Perl 5.10 though not identical. It is printing to the screen and appending a newline at the end.
qw// returns the individual string values from a space separated list of items. In Perl 5 the qw() operator was used for this.
Actually unique can also be used as a method call on the array...
examples/unique_strings_method.pl6
use v6; my @chars = <b c a d b a a a b>; my @singles = @chars.unique; say @singles.perl; # ["b", "c", "a", "d"] @singles.perl.say; # ["b", "c", "a", "d"]
... and some people will prefer to add the .say method call at the end of the expression.
Though I think this isn't as clear as having the say at the beginning.
Published on 2017-06-18