Array-Join
view release on metacpan or search on metacpan
lib/Array/Join/OO.pm view on Meta::CPAN
sub _cross_product {
map { my $a = $_; map [ $a, $_ ], $_[1]->@* } $_[0]->@*
}
sub _merge {
my ($item_a, $item_b, $opts) = @_;
$item_a = Clone::clone($item_a);
$item_b = Clone::clone($item_b);
if (ref $opts->{merge} eq "CODE") {
return $opts->{merge}->($item_a, $item_b, $opts);
}
elsif (ref $opts->{merge} eq "ARRAY") {
my @names = $opts->{merge}->@*;
$item_a->{CORE::join ".", $names[0], $_} = delete $item_a->{$_} for CORE::keys $item_a->%*;
$item_b->{CORE::join ".", $names[1], $_} = delete $item_b->{$_} for CORE::keys $item_b->%*;
return Hash::Merge::merge($item_a, $item_b);
}
elsif ($opts->{merge} && $opts->{merge} =~ /_PRECEDENT$/) {
local $Hash::Merge::behavior = $opts->{merge};
return Hash::Merge::merge($item_a, $item_b);
}
elsif ($opts->{merge}) {
return Hash::Merge::merge($item_a, $item_b);
}
else {
return [ $item_a, $item_b ]
}
}
1;
=head1 NAME
Array::Join::OO - SQL-like joins over two arrays of hashrefs
=head1 SYNOPSIS
use Array::Join::OO;
my $join = Array::Join::OO->new(
\@left,
\@right,
{
on => [
sub { $_[0]{id} },
sub { $_[0]{id} },
],
type => 'inner', # inner | left | right | outer
merge => 'LEFT_PRECEDENT',
}
);
my @rows = $join->join;
=head1 DESCRIPTION
C<Array::Join::OO> performs SQL-style joins over two Perl arrays.
Each array element is typically a hashref. Join keys are produced
by user-supplied callbacks.
The module supports C<inner>, C<left>, C<right>, and C<outer> joins
and multiple merge strategies for combining matching rows.
Multiple rows per key are supported; all matching combinations
are returned (Cartesian product).
=head1 CONSTRUCTOR
=head2 new( \@array_a, \@array_b, \%options )
Creates a join object.
Exactly two array references must be provided.
The options hash must contain an C<on> key with exactly two
code references, one per array.
=head3 Options
=over 4
=item * on => [ sub {...}, sub {...} ]
Required. Two callbacks that extract a join key from items in
the left and right arrays respectively.
=item * type => 'inner' | 'left' | 'right' | 'outer'
Join type. Defaults to C<inner>.
=item * merge => STR | ARRAY | CODE
Controls how matching rows are combined.
See L</MERGE STRATEGIES>.
=item * as => ...
Alias for C<merge>.
=back
=head1 METHODS
=head2 join
my @rows = $join->join;
Executes the join and returns a list of merged rows.
For non-inner joins, missing rows are represented as empty hashrefs.
=head2 keys
my $keys = $join->keys;
Returns a sorted arrayref of join keys used by the join.
=head2 lookups
my $lookups = $join->lookups;
Returns a deep clone of the internal lookup tables.
This data is read-only.
=head1 MERGE STRATEGIES
The C<merge> option controls how matching rows are combined.
=head2 CODE reference
merge => sub {
my ($left, $right, $opts) = @_;
...
}
Receives cloned copies of both rows and must return a single value.
=head2 ARRAY reference
merge => [ 'left', 'right' ]
All keys in each hash are renamed with the given prefixes
(e.g. C<left.id>, C<right.id>) before merging.
( run in 1.727 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )