List::GroupBy provides functions to group a list of hashrefs in to a hash of hashrefs of arrayrefs.
groupBy( [ 'primary key', 'secondary key', ... ], LIST )
If called with and array ref as the first parameter then groupBy
will group
the list by the keys provided in the array ref.
Note: undefined values for a key will be defaulted to the empty string.
Returns a hash of hashrefs of arrayrefs
groupBy( { keys => [ 'key', ... ], defaults => { 'key' => 'default', ... }, operations => { 'key' => sub, ... }, LIST )
More advanced options are available by calling groupBy
with a hash ref of
options as the first parameter. Available options are:
keys
(Required)
An array ref of the keys to use for grouping. The order of the keys dictates the order of the grouping. So the first key is the primary grouping, the second key is used for the secondary grouping under the primary grouping an so on.
defaults
(Optional)
A hash ref of defaults to use one or more keys. If a key for an item is
undefined and there's an entry in the defaults
option then that will be
used. If no default value has been supplied for a key then the empty string
will be used.
operations
(Optional)
A hash ref mapping keys to a function to use to normalise value's when grouping. If there's no entry for a key then the value is just used as is.
Each funtion is passed the value as it's only parameter and it's return value is used for the key.
Returns a hash of hashrefs of arrayrefs
Keyword::TailRecurse provides a tailRecurse
keyword that does proper tail recursion that doesn't grow the call stack. It uses functionality added in Perl 5.14 so it's a Pure Perl solution (other current solutions use XS modules).
After using the module you can precede a function call with the keyword tailRecurse
and rather adding a new entry on the call stack the function call will replace the current entry on the call stack.
note: Keyword::TailRecurse
requires features Perl v5.14 and above.
If compatibility with Sub::Call::Tail is required then you can use the subCallTail
flag to enable the tail keyword.
use Keyword::TailRecurse 'subCallTail';
sub fibonacci {
my ( $count, $previous, $current ) = @_;
return ( $previous // 0 ) if $count <= 0;
$current //= 1;
tail fibonacci ( $count - 1, $current, $previous + $current );
}
print fibonacci( 7 );
note: with Sub::Call:Tail compatibility enabled both the tailRecurse and tail keywords are available.
There's a couple of existing modules that use XS modules to provide similar functionality:
An XS
module that provides a form of tail recursion - limited to recursing
into the same function it's used from.
An XS
module that provides a generic tail recursion.
PartialApplilcation is a small module to handle partially applying parameters to functions - a common technique used in the functional programming style of coding.
Partially applies the parameters to the function, giving a new function reference.
To partially apply parameters to an object method, pass a function reference to the method as the first parameter, the object instance as the second, followed by the parameters to be partially applied.
my $object = Class->new();
my $partiallyAppliedMethod = partiallyApply( \&Class::method, $object, 1, 2, 3 );
$partiallyAppliedMethod->(4, 5, 6); # equivilant of $object->method(1, 2, 3, 4, 5, 6)
A function reference to the partially applied function.
Partially applies the parameters to the end of the function call - useful for when you're using named parameters and you want to make sure that the partially applied parameters are the ones used.
sub testSub {
my %params = @_;
print "$_ - $params{$_}\n" for keys %params;
}
my $partiallyAppliedFunction = partiallyApplyRight( \&testSub, asdf => 99 );
$partiallyAppliedFunction->(asdf => 100); # outputs: asdf - 99
A function reference to the partially applied function.
Partially applies the parameters based upon the parameterBitmap. An entry of 1 in the parameterBitmap will use a partially applied parameter and an entry of 0 will use a parameter from the call.
sub testSub {
print join(", ", @_) ."\n";
}
my $partiallyAppliedFunction = partiallyApplyN( \&testSub, [ 1, 0, 1, 0 ], 1, 2, 3, 4, 5 );
$partiallyAppliedFunction->('a', 'b', 'c', 'd'); # outputs: 1, a, 2, b, 3, 4, 5, c, d
This does allow you to partially apply parameter to a method call without specifying the object instance to apply it to multiple instances.
my $partiallyAppliedMethod2 = partiallyApplyN( \&Class::method, [ 0, 1, 1, 1 ], 1, 2, 3 );
$partiallyAppliedMethod2->($object1, 4, 5); # equivilant to $object1->method(1, 2, 3, 4, 5)
$partiallyAppliedMethod2->($object2, 6, 7); # equivilant to $object2->method(1, 2, 3, 6, 7)
A function reference to the partially applied function.