Article Series

This article series discuss more than 30 different programming languages. Please read overview before you read any of the details.

Playing with Records Related Articles.

Where to Discuss?

Local Group

Preface

Goal: Continue Part One


4: List Comprehension Equivalent.

Using Map and Grep.

Perl is actually great. Although the perl syntax is not as concise as perl list comprehension, It natively has support for map, and filtering with grep.

Simple Example

Consider examine map, applying to our songs records.

my @songs_title = map {
     @$_{'title'}
   } @MySongs::songs;
say join(':', @songs_title);

With the result as below:

Cantaloupe Island:Let It Be:Knockin' on Heaven's Door:Emotion:The River

And then go further with grep.

my @songs_tags = map {
    $_->{'tags'}
  } grep {
    exists($_->{'tags'}) 
  } @MySongs::songs;

for my $tags ( @songs_tags ) {
  say join(":", @$tags);
}

With the result as below:

60s:jazz
60s:rock
70s:rock
70s:pop

we can examine the object shown in output result above.

Perl: Examining Map and Grep

Flatten

With just a little modification, we can flatten the array.

use MySongs;

my @songs_tags = map {
    @{ $_->{'tags'} }
  } grep {
    exists($_->{'tags'}) 
  } @MySongs::songs;

say join(":", @songs_tags);

This should be, without a doubt, almost list comprehension. With the result similar as below record:

❯ ./12-flatten.pl
60s:jazz:60s:rock:70s:rock:70s:pop

Perl: List Comprehension Map and Grep: Flatten

Unique

And we can also chain the function, using previously grabbed code from stackoverflow.

use MySongs;

my %seen;

my @songs_tags = grep {
    !$seen{$_}++
  } map {
    @{ $_->{'tags'} }
  } grep {
    exists($_->{'tags'}) 
  } @MySongs::songs;

say join(":", @songs_tags);

With the result similar as below record:

❯ ./13-unique.pl
60s:jazz:rock:70s:pop

Perl: List Comprehension Map and Grep: Unique


5: Approach in Solving Unique

A custom example, that you can rewrite.

An Algorithm Case

Why reinvent the wheel?

The same reason as any other articles.

x:xs Pattern Matching

The same with any other articles as well.

Exclude Function

The exclude function is just a filter with below details:

my @tags = ('rock',
  'jazz', 'rock', 'pop', 'pop');

sub exclude {
  my ($value, @tags) = @_;
  grep(!/$value/, @tags);
}

say join(':', exclude('rock', @tags));

With the result as below array:

❯ ./21-exclude.pl
jazz:pop:pop

Perl: Exclude Function

Recursive Unique Function

With exclude function above, we can build unique function recursively.

Since we are going to reuse the unique approach in other script. It is better to bundle the script in its own perl module.

package MyHelperUnique;

use strict;
use warnings;

sub unique {
  if (@_ <= 1) {
    @_;
  } else {
    # array[$head:@tail]
    my $head = shift;
    my @tail = @_;

    # recursive unique
    my @xcld = grep(!/$head/, @tail);
    my @uniq = unique(@xcld);

    # returned array
    unshift @uniq, $head;
    @uniq;
  }
}

1;

The return values is in array.

![Perl: The Unique Function][img-my-unique-perl]

Using Unique Module

There is nothing to say in this code below. Just apply unique function to our song records.

use MyHelperUnique;

my @tags = ('rock',
  'jazz', 'rock', 'pop', 'pop');

say join(':',
  MyHelperUnique::unique(@tags));

With the result as below array:

❯ ./22-unique-a.pl
rock:jazz:pop

Perl: Using Recursive Unique Function

Applying Unique to Songs Records

Now we can apply the method to our unique song challenge.

use MySongs;
use MyHelperFlatten;
use MyHelperUnique;

say join(':',
  MyHelperUnique::unique(
    MyHelperFlatten::flatten(
      @MySongs::songs
)));

With the same result as below

Perl: Solving Unique Song

❯ ./22-unique-b.pl
60s:jazz:rock:70s:pop

What is Next 🤔?

We have alternative way to extract the record structure. With pattern similar to list comprehension.

Consider continue reading [ Raku - Playing with Records - Part One ].