Camelia

Arrays with unique values in Perl 6

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.

Note! This site is about Perl 6.
If you are looking for a solution for Perl 5, please check out the Perl 5 tutorial.
Specifially there is a related article: Unique values in an array in Perl 5.

Arrays with unique values

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"]

Eliminate consecutive duplicate values with squish

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"]

Count number of occurrences with .Bag

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 

Perl 6 Comments

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.

Method calls

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.


The Perl 6 Tricks and Treats newsletter has been around for a while. If you are interested to get special notification when there is new content on this site, it is the best way to keep track:
Email:
Full name:
This is a newsletter temporarily running on my personal site (szabgab.com) using Mailman, till I implement an alternative system in Perl 6.
Gabor Szabo
Written by Gabor Szabo

Published on 2017-06-18



Comments

In the comments, please wrap your code snippets within <pre> </pre> tags and use spaces for indentation.
comments powered by Disqus
Suggest a change
Elapsed time: 2.37670526

Perl 6 Tricks and Treats newsletter

Register to the free newsletter now, and get updates and news.
Email:
Name: