File Coverage

blib/lib/List/Util/groupby.pm
Criterion Covered Total %
statement 11 52 21.1
branch 0 6 0.0
condition 0 9 0.0
subroutine 4 6 66.6
pod 2 2 100.0
total 17 75 22.6


line stmt bran cond sub pod time code
1             package List::Util::groupby;
2              
3 1     1   504019 use 5.010001;
  1         4  
4 1     1   7 use strict;
  1         2  
  1         39  
5 1     1   6 use warnings;
  1         2  
  1         97  
6              
7 1     1   7 use Exporter 'import';
  1         3  
  1         619  
8              
9             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
10             our $DATE = '2023-11-20'; # DATE
11             our $DIST = 'List-Util-groupby'; # DIST
12             our $VERSION = '0.004'; # VERSION
13              
14             our @EXPORT_OK = qw(
15             groupby
16             hgroupby
17             );
18              
19             sub groupby(&;@) { ## no critic: Subroutines::ProhibitSubroutinePrototypes
20 0     0 1   my $code = shift;
21              
22 0           my @result;
23 0           my $index = -1;
24 0           for my $item (@_) {
25 0           $index++;
26 0           my $result_index;
27 0           { local $_ = $item; $result_index = $code->($item, $index) }
  0            
  0            
28 0 0         if (ref($result_index) eq 'ARRAY') {
29 0           my $temp = \@result;
30 0           for my $i (0 .. $#{ $result_index }) {
  0            
31 0   0       $temp->[ $result_index->[$i] ] //= [];
32 0           $temp = $temp->[ $result_index->[$i] ];
33             }
34 0           push @$temp, $item;
35             } else {
36 0   0       $result[$result_index] //= [];
37 0           push @{ $result[$result_index] }, $item;
  0            
38             }
39             }
40 0           @result;
41             }
42              
43             sub hgroupby(&;@) { ## no critic: Subroutines::ProhibitSubroutinePrototypes
44 0     0 1   my $code = shift;
45              
46 0           my %result;
47 0           my $index = -1;
48 0           for my $item (@_) {
49 0           $index++;
50 0           my $result_index;
51 0           { local $_ = $item; $result_index = $code->($item, $index) }
  0            
  0            
52 0 0         if (ref($result_index) eq 'ARRAY') {
53 0           my $temp = \%result;
54 0           for my $i (0 .. $#{ $result_index }) {
  0            
55 0 0 0       $temp->{ $result_index->[$i] } //= $i == $#{ $result_index } ? [] : {};
  0            
56 0           $temp = $temp->{ $result_index->[$i] };
57             }
58 0           push @$temp, $item;
59             } else {
60 0   0       $result{$result_index} //= [];
61 0           push @{ $result{$result_index} }, $item;
  0            
62             }
63             }
64 0           %result;
65             }
66              
67             1;
68             # ABSTRACT: Group items of a list into several (possibly multilevel) buckets
69              
70             __END__