# NAME

List::GroupBy - Group a list of hashref's to a multilevel hash of hashrefs of arrayrefs

# SYNOPSIS

   use List::GroupBy qw( groupBy );

   my @list = (
       { firstname => 'Fred',   surname => 'Blogs', age => 20 },
       { firstname => 'George', surname => 'Blogs', age => 30 },
       { firstname => 'Fred',   surname => 'Blogs', age => 65 },
       { firstname => 'George', surname => 'Smith', age => 32 },
       { age => 99 },
   );

   my %groupedList = groupBy ( [ 'surname', 'firstname' ], @list );

   # %groupedList => (
   #     'Blogs' => {
   #         'Fred' => [
   #             { firstname => 'Fred',   surname => 'Blogs', age => 20 },
   #             { firstname => 'Fred',   surname => 'Blogs', age => 65 },
   #         ],
   #         'George' => [
   #             { firstname => 'George', surname => 'Blogs', age => 30 },
   #         ],
   #     },
   #     'Smith' => {
   #         'George' => [
   #             { firstname => 'George', surname => 'Smith', age => 32 },
   #         ],
   #     },
   #     '' => {
   #         '' => [
   #             { age => 99 },
   #         },
   #     },
   # )


   %groupedList = groupBy(
       {
           keys => [ 'surname', 'firstname' ],
           defaults => { surname => 'blogs' }
       },
       @list
   );

   # %groupedList => (
   #     Blogs => {
   #         Fred => [
   #             { firstname => 'Fred',   surname => 'Blogs', age => 20 },
   #             { firstname => 'Fred',   surname => 'Blogs', age => 65 },
   #         ],
   #         George => [
   #             { firstname => 'George', surname => 'Blogs', age => 30 },
   #         ],
   #         '' => [
   #             { age => 99 },
   #         ],
   #     },
   #     Smith => {
   #         George => [
   #             { firstname => 'George', surname => 'Smith', age => 32 },
   #         ],
   #     },
   # )


   %groupedList = groupBy (
       {
           keys => [ 'surname', 'firstname' ],
           defaults => { surname => 'Blogs' },
           operations => { surname => sub { uc $_[0] } },
       },
       @list
   );

   # %groupedList => (
   #     BLOGS => {
   #         Fred => [
   #             { firstname => 'Fred',   surname => 'Blogs', age => 20 },
   #             { firstname => 'Fred',   surname => 'Blogs', age => 65 },
   #         ],
   #         George => [
   #             { firstname => 'George', surname => 'Blogs', age => 30 },
   #         ],
   #         '' => [
   #             { age => 99 },
   #         ],
   #     },
   #     SMITH => {
   #         George => [
   #             { firstname => 'George', surname => 'Smith', age => 32 },
   #         ],
   #     },
   # )

# DESCRIPTION

List::GroupBy provides functions to group a list of hashrefs in to a hash of
hashrefs of arrayrefs.

# FUNCTIONS

- `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

# LICENSE

Copyright (C) Jason Cooper.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

# AUTHOR

Jason Cooper <[email protected]>