doing an inner join via cross-product

2020-07-19 Thread Joseph Brenner
I was thinking about the cross-product operator the other day,
and I was wondering if there might be a convenient way of
filtering the resulting cartesian product to do something like a
database inner join:

my @level  = ( godzilla => 9 ,gremlin => 3, hanuman => 5 );
my @origin = ( godzilla => 'jp',  tingler => 'us',  hanuman => 'il' );

my @results = ( @level X @origin ).grep({ $_[0].keys eq $_[1].keys });
say @results;  # ((godzilla => 6 godzilla => jp) (hanuman => 5
hanuman => il))

That's easy enough, though the resulting data structure isn't very neat.
I started looking for ways to rearrange it:

my %joined;
for @results -> $row {
say "row: ", $row;  # e.g. row: (godzilla => 9 godzilla => jp)
say $row.map({ .keys });# e.g. ((godzilla) (godzilla))
say $row.map({ .values });  # e.g. ((9) (jp))

my $monster =| $row[0].keys;  # e.g. godzilla
my @attributes =| $row.map({ .values });  # e.g. [9 jp]
%joined{ $monster } = @attributes;
}
say %joined;  # {godzilla => [9 jp], hanuman => [5 il]}

I can do it more compactly, but it risks getting unreadable:

my %joined2 =| @results.map({ $_[0].keys => .map({ .values }).flat  });

In any case, the %joined structure feels more perlish, for
example it's easier to use it to generate reports:

for %joined.keys -> $key {
printf "%12s: level: %-2d origin: %3s\n", $key, %joined{ $key }.flat;
}
# hanuman: level: 5  origin:  il
#godzilla: level: 9  origin:  jp

Is there some neater way of doing this that I'm missing?


Re: doing an inner join via cross-product

2020-07-19 Thread Darren Duncan
This reminds me of my 2009 Set::Relation Perl module, which works to help you do 
SQL features like this in your application, but will soon be superseded by 
another module that also has a Raku version. -- Darren Duncan


On 2020-07-19 1:02 p.m., Joseph Brenner wrote:

I was thinking about the cross-product operator the other day,
and I was wondering if there might be a convenient way of
filtering the resulting cartesian product to do something like a
database inner join:

 my @level  = ( godzilla => 9 ,gremlin => 3, hanuman => 5 );
 my @origin = ( godzilla => 'jp',  tingler => 'us',  hanuman => 'il' );

 my @results = ( @level X @origin ).grep({ $_[0].keys eq $_[1].keys });
 say @results;  # ((godzilla => 6 godzilla => jp) (hanuman => 5
hanuman => il))

That's easy enough, though the resulting data structure isn't very neat.
I started looking for ways to rearrange it:

 my %joined;
 for @results -> $row {
 say "row: ", $row;  # e.g. row: (godzilla => 9 godzilla => jp)
 say $row.map({ .keys });# e.g. ((godzilla) (godzilla))
 say $row.map({ .values });  # e.g. ((9) (jp))

 my $monster =| $row[0].keys;  # e.g. godzilla
 my @attributes =| $row.map({ .values });  # e.g. [9 jp]
 %joined{ $monster } = @attributes;
 }
 say %joined;  # {godzilla => [9 jp], hanuman => [5 il]}

I can do it more compactly, but it risks getting unreadable:

 my %joined2 =| @results.map({ $_[0].keys => .map({ .values }).flat  });

In any case, the %joined structure feels more perlish, for
example it's easier to use it to generate reports:

 for %joined.keys -> $key {
 printf "%12s: level: %-2d origin: %3s\n", $key, %joined{ $key }.flat;
 }
 # hanuman: level: 5  origin:  il
 #godzilla: level: 9  origin:  jp

Is there some neater way of doing this that I'm missing?



Raku version of "The top 10 tricks of Perl one-liners" ?!?

2020-07-19 Thread William Michels via perl6-users
Hello,

I ran across this 2010 Perl(5) article on the Oracle Linux Blog:

"The top 10 tricks of Perl one-liners"
https://blogs.oracle.com/linux/the-top-10-tricks-of-perl-one-liners-v2

Q1. Now that it's a decade later--and Raku (née Perl6) has hit the
scene--can someone translate the 'top ten tricks' in the blog article
above into Raku?

Q2. Are many of the ten Perl(5) one-liner 'tricks' unnecessary in Raku
(better defaults, more regularized regexes, etc.)?

Best, Bill.