PWC183 - Unique Array


Here we are with TASK #1 from The Weekly Challenge #183. Enjoy!

The challenge

You are given list of arrayrefs.

Write a script to remove the duplicate arrayrefs from the given list.

Example 1

Input: @list = ([1,2], [3,4], [5,6], [1,2])
Output: ([1,2], [3,4], [5,6])

*Example 2

Input: @list = ([9,1], [3,7], [2,5], [2,5])
Output: ([9, 1], [3,7], [2,5])

The questions

It would be interesting to know what is inside the array references, and if they are all of the same size!

I will assume that the arrayrefs will contain some “stuff” that contains no loop references and no blessed references.

The solution

The general algorithm will be the same:

  • figure out a string representation for the array ref
  • use the string as a key in a hash, to filter out copies efficiently.

With Raku we will use method .gist for the string representation:

#!/usr/bin/env raku
use v6;
sub MAIN {
   my @list = [1,2], [3,4], [5,6], [1,2];
   .say for remove-duplicate-subarrays(@list);
sub remove-duplicate-subarrays (@a) { my %seen; @a.grep({!%seen{.gist}++}) }

For the Perl alternative, we’re going to leverage the stock JSON encoder that comes in CORE:

#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';

use JSON::PP;

my @list = ([1,2], [3,4], [5,6], [1,2]);
say JSON::PP::encode_json($_) for remove_duplicate_subarrays(@list);

sub remove_duplicate_subarrays (@l) {
   state $encoder = JSON::PP->new->ascii->canonical;
   my %seen;
   grep {!$seen{$encoder->encode($_)}++} @l;

This will break in case of circular data structures, blessed stuff… but we’re excluding them here, right?!?

Stay safe!

Comments? Octodon, Twitter, GitHub, Reddit, or drop me a line!