Perl Weekly Challenge 253: Split Strings
These are some answers to the Week 253, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on January 28, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
Task 1: Split Strings
You are given an array of strings and a character separator.
Write a script to return all words separated by the given character excluding empty string.
Example 1
Input: @words = ("one.two.three","four.five","six")
$separator = "."
Output: "one","two","three","four","five","six"
Example 2
Input: @words = ("$perl$$", "$$raku$")
$separator = "$"
Output: "perl","raku"
Split Strings in Raku
Since we are passing two very different arguments to our split-strings
subroutine, a single character and an array of strings, I thought it was a good opportunity to brush up my knowledge of named arguments to a subroutine. The arguments are supplied at the subroutine call as a list of pairs using the pair constructor syntax. In the subroutine signature, the parameters are retrieved with the so-called colon-pair syntax.
Otherwise, this is quite simple. We're using a grep
to remove empty strings from the result.
sub split-strings (:$sep, :@strings) {
my @result = grep { /\w+/ }, flat
map { split $sep, $_ }, @strings;
return @result;
}
my @tests = {
'separator' => '.',
'string' => ("one.two.three","four.five","six")
}, {
'separator' => '$',
'string' => ('$perl$$', '$$raku$')};
for @tests -> %test {
printf "%-30s => ", %test<string>;
say split-strings(sep => %test<separator>,
strings => %test<string>);
}
This program displays the following output:
$ raku ./split-strings.raku
one.two.three four.five six => [one two three four five six]
$perl$$ $$raku$ => [perl raku]
Split Strings in Perl
This is a port to Perl of the above Raku program, except that we use here normal positional parameters. Please loop at the previous section if you need further explanations. Note that we use the quotemeta
operator to make sure that the separator will be properly backslashed (to transform the separator string into a regex).
use strict;
use warnings;
use feature 'say';
sub split_strings {
my ($sep, @strings) = @_;
$sep = quotemeta $sep;
my @result = grep { /\w+/ }
map { split $sep, $_ } @strings;
return @result;
}
my @tests = ( [ '.', ["one.two.three","four.five","six"] ],
[ '$', ['$perl$$', '$$raku$'] ] );
for my $test (@tests) {
printf "%-30s => ", "@{$test->[1]}";
say join " ", split_strings $test->[0], @{$test->[1]};
}
This program displays the following output:
$ perl ./split-strings.pl
one.two.three four.five six => one two three four five six
$perl$$ $$raku$ => perl raku
Wrapping up
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on February 4, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment