This question continues the previous one about filtering (variable names change from array
and search
to source
and keys
).
Suppose there are even more elements and more keys. The program should print only those elements @source
that begin with any of @keys
. So it jjjjk
will be printed, but jjjkk
it will not.
Here's the easiest way to solve the problem, but it is too slow to use:
my @source = "aaaaa" .. "kkkkk";
my @keys = "aaaa" .. "jjjj";
.put for @source .grep: /^ @source /;
# produced 4 elements in 60 seconds
# out of 10 ** 4 * 11 = 110_000
# will take ~19 days to finish
Use .Any
and .starts-with()
makes it ~ 100 times faster:
my @source = "aaaaa" .. "kkkkk";
my @keys = "aaaa" .. "jjjj";
my $keys_any = @keys.any;
.put for @source .grep: *.starts-with($keys_any);
# produced 700 elements in 110 seconds
# will take ~4.5 hours
If we precompile the regular expression, it works much (~ 15000x) faster:
my @source = "aaaaa" .. "kkkkk";
my @keys = "aaaa" .. "jjjj";
my $keys = "/@keys.join('|')/".EVAL;
.put for @source .grep: /^ <$keys> /;
# produced all the elements in 100 seconds
, , , . , Set
of @keys
@source
:
my @source = "aaaaa" .. "kkkkk";
my @keys = "aaaa" .. "jjjj";
my $keys = @keys.Set;
for @source -> $str {
my $substring = $str.substr(0, 4);
if $substring (elem) $keys {
put $str;
next;
}
}
# produced all the elements in 3 seconds
, ?