doing an inner join via cross-product
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
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" ?!?
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.