NAME
Array::Join - performs SQL-like joins on arrays
SYNOPSIS
use Array::Join;
my @arr_a = (
    { id => 1, name => 'Alice' },
    { id => 2, name => 'Bob' },
);
my @arr_b = (
    { uid => 1, email => 'alice@example.com' },
    { uid => 3, email => 'carol@example.com' },
);
my @joined = join_arrays(
    \@arr_a,
    \@arr_b,
    sub { $_->{id} },
    sub { $_->{uid} },
    {
        type  => 'left',
        merge => [ 'a', 'b' ],
    }
);
# Result:
# (
#   { 'a.id' => 1, 'a.name' => 'Alice', 'b.uid' => 1, 'b.email' => 'alice@example.com' },
#   { 'a.id' => 2, 'a.name' => 'Bob' },  # No match in B
# )
DESCRIPTION
Array::Join provides SQL-style joining functionality on arrayrefs of hashrefs.
It supports the four common SQL join types (inner, left, right, outer) and provides options to control merging behavior.
FUNCTIONS
join_arrays
@result = join_arrays($arr_a, $arr_b, $key_sub_a, $key_sub_b, \%opts);
Performs a join between two arrayrefs of hashrefs, using two key extractor functions. Returns a list of joined results.
$arr_a,$arr_bArrayrefs of hashrefs to join.
$key_sub_a,$key_sub_bCode references that return the join key for a given item in the array.
sub { $_->{foo} }\%opts(optional)A hashref of options to configure the join behavior.
Options
typeThe type of join to perform. One of:
'inner'(default)- 
Return only matching pairs (intersection of keys in both inputs).
 'left'- 
Include all entries from the left side, and matching entries from the right side if any.
 'right'- 
Include all entries from the right side, and matching entries from the left side if any.
 'outer'- 
Include all keys present in either array (full outer join). Rows without matches are joined with
undef. 
mergeControls how the matched pairs are flattened into a single hash per output row.
This can be:
- A CODEREF
 - 
A sub that receives two hashrefs (left and right item) and returns a merged hashref.
merge => sub { my ($left, $right) = @_; return { %$left, %$right }; } - An ARRAYREF
 - 
An arrayref of two prefix strings to apply to the keys of each side. For example:
merge => [ 'left', 'right' ]Would turn:
{ name => 'Alice' } and { email => 'a@example.com' }into:
{ 'left.name' => 'Alice', 'right.email' => 'a@example.com' } 'LEFT_PRECEDENT'or'RIGHT_PRECEDENT'or other Hash::Merge behaviors- 
These use the Hash::Merge behaviors to merge the hashes. For example:
merge => 'LEFT_PRECEDENT'will favor keys from the left hashref when they conflict.
 true value- 
Any other true value will merge using Hash::Merge’s default behavior.
 false/undef- 
If
mergeis not provided or false, the result will be a list of arrayrefs with two elements (left, right). For example:[ $item_from_a, $item_from_b ] 
INTERNAL FUNCTIONS
These are not exported.
make_lookup($arrayref, $key_sub)
Creates a hashref mapping keys to arrayrefs of array indexes for faster lookup.
make_keys($lookup_a, $lookup_b, \%opts)
Generates the list of join keys to consider, depending on join type.
make_joined(...)
Assembles the actual matching row pairs based on the join keys.
flatten_result($arrayref_of_pairs, \%opts)
Converts pairs of hashrefs into merged single hashes, based on merge option.
cross_product($listref1, $listref2)
Creates the full cross-product (i.e., every combination of pairings) between two lists of indexes.
EXPORTS
Only one function is exported by default:
join_arrays
CAVEATS
This was built for convenience, not performance. It's never been tested for very large arrays
TODO
Test comparing behaviour with SQL
More tests
Joining more than 2 arrays
SEE ALSO
AUTHOR
Simone Cesano <scesano@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2025 by Simone Cesano.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.