File Coverage

blib/lib/List/Util/Uniq.pm
Criterion Covered Total %
statement 121 121 100.0
branch 44 50 88.0
condition 8 18 44.4
subroutine 27 27 100.0
pod 20 20 100.0
total 220 236 93.2


line stmt bran cond sub pod time code
1             package List::Util::Uniq;
2              
3 2     2   459414 use strict;
  2         6  
  2         81  
4 2     2   13 use warnings;
  2         4  
  2         193  
5              
6 2     2   18 use Exporter qw(import);
  2         4  
  2         1287  
7              
8             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
9             our $DATE = '2024-01-19'; # DATE
10             our $DIST = 'List-Util-Uniq'; # DIST
11             our $VERSION = '0.008'; # VERSION
12              
13             our @EXPORT_OK = qw(
14             uniq
15             uniqint
16             uniqnum
17             uniqstr
18              
19             uniq_adj
20             uniq_adj_ci
21             uniq_ci
22             is_uniq
23             is_uniq_ci
24             is_monovalued
25             is_monovalued_ci
26              
27             dupe
28             dupeint
29             dupenum
30             dupestr
31              
32             dupe_ci
33              
34             pushuniq
35             pushuniqint
36             pushuniqnum
37             pushuniqstr
38             );
39              
40             sub uniq_adj {
41 2     2 1 12184 my @res;
42              
43 2 50       10 return () unless @_;
44 2         5 my $last = shift;
45 2         5 push @res, $last;
46 2         18 for (@_) {
47 12 0 33     27 next if !defined($_) && !defined($last);
48             # XXX $_ becomes stringified
49 12 100 33     62 next if defined($_) && defined($last) && $_ eq $last;
      66        
50 10         21 push @res, $_;
51 10         23 $last = $_;
52             }
53 2         20 @res;
54             }
55              
56             sub uniq_adj_ci {
57 1     1 1 4 my @res;
58              
59 1 50       5 return () unless @_;
60 1         3 my $last = shift;
61 1         2 push @res, $last;
62 1         4 for (@_) {
63 6 0 33     14 next if !defined($_) && !defined($last);
64             # XXX $_ becomes stringified
65 6 100 33     38 next if defined($_) && defined($last) && lc($_) eq lc($last);
      66        
66 4         7 push @res, $_;
67 4         8 $last = $_;
68             }
69 1         8 @res;
70             }
71              
72             sub uniq_ci {
73 2     2 1 4912 my @res;
74              
75             my %mem;
76 2         0 my $undef_added;
77 2         6 for (@_) {
78 13 100       26 if (defined) {
79 11 100       37 push @res, $_ unless $mem{lc $_}++;
80             } else {
81 2 100       7 push @res, $_ unless $undef_added++;
82             }
83             }
84 2         19 @res;
85             }
86              
87             sub is_uniq {
88 5     5 1 6482 my %vals;
89 5         14 for (@_) {
90 7 100       32 return 0 if $vals{$_}++;
91             }
92 4         26 1;
93             }
94              
95             sub is_uniq_ci {
96 5     5 1 3243 my %vals;
97 5         12 for (@_) {
98 7 100       33 return 0 if $vals{lc $_}++;
99             }
100 3         11 1;
101             }
102              
103             sub is_monovalued {
104 5     5 1 4598 my %vals;
105 5         14 for (@_) {
106 7         18 $vals{$_} = 1;
107 7 100       33 return 0 if keys(%vals) > 1;
108             }
109 3         14 1;
110             }
111              
112             sub is_monovalued_ci {
113 5     5 1 5613 my %vals;
114 5         14 for (@_) {
115 7         17 $vals{lc $_} = 1;
116 7 100       24 return 0 if keys(%vals) > 1;
117             }
118 4         20 1;
119             }
120              
121             sub uniqint {
122 2     2 1 5016 my (@uniqs, %vals);
123 2         6 for (@_) {
124 2     2   14 no warnings 'numeric';
  2         4  
  2         257  
125 8 100       37 ++$vals{int $_} == 1 and push @uniqs, $_;
126             }
127 2         11 @uniqs;
128             }
129              
130             sub uniqnum {
131 2     2 1 4821 my (@uniqs, %vals);
132 2         7 for (@_) {
133 2     2   13 no warnings 'numeric';
  2         4  
  2         336  
134 8 100       42 ++$vals{$_+0} == 1 and push @uniqs, $_;
135             }
136 2         15 @uniqs;
137             }
138              
139             sub uniqstr {
140 4     4 1 9 my (@uniqs, %vals);
141 4         10 for (@_) {
142 19 100       60 ++$vals{$_} == 1 and push @uniqs, $_;
143             }
144 4         33 @uniqs;
145             }
146              
147 2     2 1 448039 sub uniq { goto \&uniqstr }
148              
149             sub dupeint {
150 6     6 1 6256 my (@dupes, %vals);
151 6         15 for (@_) {
152 2     2   10 no warnings 'numeric';
  2         5  
  2         213  
153 20 100       62 ++$vals{int $_} > 1 and push @dupes, $_;
154             }
155 6         35 @dupes;
156             }
157              
158             sub dupenum {
159 5     5 1 3865 my (@dupes, %vals);
160 5         17 for (@_) {
161 2     2   11 no warnings 'numeric';
  2         3  
  2         1223  
162 18 100       64 ++$vals{$_+0} > 1 and push @dupes, $_;
163             }
164 5         33 @dupes;
165             }
166              
167             sub dupestr {
168 10     10 1 4804 my (@dupes, %vals);
169 10         29 for (@_) {
170 46 100       144 ++$vals{$_} > 1 and push @dupes, $_;
171             }
172 10         84 @dupes;
173             }
174              
175 5     5 1 5077 sub dupe { goto \&dupestr }
176              
177             sub dupe_ci {
178 2     2 1 4678 my @res;
179              
180             my %mem;
181 2         0 my $undef_added;
182 2         6 for (@_) {
183 13 100       27 if (defined) {
184 11 100       38 push @res, $_ if $mem{lc $_}++;
185             } else {
186 2 100       8 push @res, $_ if $undef_added++;
187             }
188             }
189 2         16 @res;
190             }
191              
192             sub pushuniqstr(\@@) { ## no critic: Subroutines::ProhibitSubroutinePrototypes
193 2     2 1 957 my $ary = shift;
194              
195 2         4 my %vals;
196 2         6 for (@$ary) { $vals{$_}++ }
  12         28  
197              
198 2         5 for my $item (@_) {
199 8 100       30 next if $vals{$item}++;
200 2         6 push @$ary, $item;
201             }
202             }
203              
204             sub pushuniqnum(\@@) { ## no critic: Subroutines::ProhibitSubroutinePrototypes
205 1     1 1 7722 my $ary = shift;
206              
207 1         3 my %vals;
208 1         3 for (@$ary) { $vals{$_+0}++ }
  4         24  
209              
210 1         3 for my $item (@_) {
211 6 100       51 next if $vals{$item+0}++;
212 2         7 push @$ary, $item;
213             }
214             }
215              
216             sub pushuniqint(\@@) { ## no critic: Subroutines::ProhibitSubroutinePrototypes
217 1     1 1 4393 my $ary = shift;
218              
219 1         3 my %vals;
220 1         3 for (@$ary) { $vals{int $_}++ }
  4         15  
221              
222 1         3 for my $item (@_) {
223 6 100       22 next if $vals{int $item}++;
224 1         3 push @$ary, $item;
225             }
226             }
227              
228 1     1 1 4377 sub pushuniq(\@@) { goto \&pushuniqstr } ## no critic: Subroutines::ProhibitSubroutinePrototypes
229              
230             1;
231             # ABSTRACT: List utilities related to finding unique items
232              
233             __END__