File Coverage

blib/lib/Util/Underscore/ListUtils.pm
Criterion Covered Total %
statement 53 53 100.0
branch 26 26 100.0
condition n/a
subroutine 6 6 100.0
pod n/a
total 85 85 100.0


line stmt bran cond sub pod time code
1             package Util::Underscore::ListUtils;
2              
3             #ABSTRACT: Interface to List::Util and List::MoreUtils
4              
5 12     12   78 use strict;
  12         26  
  12         307  
6 12     12   57 use warnings;
  12         28  
  12         6613  
7              
8             ## no critic (ProhibitMultiplePackages)
9             package # hide from PAUSE
10             _;
11              
12             ## no critic (ProhibitSubroutinePrototypes)
13              
14              
15             # this function generates max_by, max_str_by, min_by, min_str_by
16             my $minmax_by = sub {
17             my ($is_less_than) = @_;
18              
19             return sub (&@) {
20 12     12   12691 my $key_func = shift;
21              
22 12 100       43 return if not defined wantarray; # nop in void context
23 11 100       37 return if not @_;
24 9 100       31 return $_[0] if not @_ > 1;
25              
26 7 100       20 if (wantarray) {
27 2         5 my $max_key = do {
28 2         6 local *_ = \$_[0];
29 2         5 $key_func->();
30             };
31 2         10 my @max_elems = shift;
32 2         5 for (@_) {
33 8         17 my $key = $key_func->();
34 8 100       28 next if $is_less_than->($key, $max_key);
35 4 100       9 if ($is_less_than->($max_key, $key)) {
36 2         3 $max_key = $key;
37 2         25 @max_elems = ();
38             }
39 4         8 push @max_elems, $_;
40             }
41 2         12 return @max_elems;
42             }
43             else {
44 5         9 my $max_elem = \shift;
45 5         11 my $max_key = do {
46 5         13 local *_ = $max_elem;
47 5         13 $key_func->();
48             };
49 5         28 for (@_) {
50 13         28 my $key = $key_func->();
51 13 100       50 if ($is_less_than->($max_key, $key)) {
52 5         9 $max_key = $key;
53 5         12 $max_elem = \$_;
54             }
55             }
56 5         24 return $$max_elem;
57             }
58             };
59             };
60              
61             *max_by = $minmax_by->(sub { $_[0] < $_[1] });
62             *max_str_by = $minmax_by->(sub { $_[0] lt $_[1] });
63             *min_by = $minmax_by->(sub { $_[1] < $_[0] });
64             *min_str_by = $minmax_by->(sub { $_[1] lt $_[0] });
65              
66              
67             sub uniq_by (&@) {
68 7     7   5214 my $key_func = shift;
69              
70 7 100       23 if (not defined wantarray) {
71 1         18 Carp::carp "Useless use of _::uniq_by in void context";
72 1         539 return;
73             }
74              
75 6 100       18 if (@_ <= 1) {
76 4 100       18 return @_ if wantarray;
77 2         10 return 0+@_;
78             }
79              
80             # caller context is propagated to grep, so this does the right thing.
81 2         5 my %seen;
82 2         5 grep { not $seen{ $key_func->() }++ } @_;
  12         51  
83             }
84              
85              
86             sub classify (&@) {
87 4     4   2108 my $key_func = shift;
88 4 100       16 return if not @_;
89 3 100       11 if (not defined wantarray) {
90 1         18 Carp::carp "Useless use of _::classify in void context";
91 1         504 return;
92             }
93 2         6 my %categories;
94 2         5 push @{ $categories{ $key_func->() } }, $_ for @_;
  12         54  
95 2 100       25 (wantarray) ? %categories : \%categories;
96             }
97              
98              
99             ## no critic (ProtectPrivateVars)
100             $Util::Underscore::_ASSIGN_ALIASES->(
101             'List::Util',
102             reduce => 'reduce',
103             any => 'any',
104             all => 'all',
105             none => 'none',
106             max => 'max',
107             max_str => 'maxstr',
108             min => 'min',
109             min_str => 'minstr',
110             sum => 'sum',
111             product => 'product',
112             pairgrep => 'pairgrep',
113             pairfirst => 'pairfirst',
114             pairmap => 'pairmap',
115             shuffle => 'shuffle',
116             );
117              
118             ## no critic (ProtectPrivateVars)
119             $Util::Underscore::_ASSIGN_ALIASES->(
120             'List::MoreUtils',
121             first => 'first_value',
122             first_index => 'first_index',
123             last => 'last_value',
124             last_index => 'last_index',
125             natatime => 'natatime',
126             uniq => 'uniq',
127             part => 'part',
128             each_array => 'each_arrayref',
129             );
130              
131             sub zip {
132 1     1   8913 goto &List::MoreUtils::zip; # adios, prototypes!
133             }
134              
135             1;
136              
137             __END__