1 |
56 |
alirezamon |
package List::MoreUtils;
|
2 |
|
|
|
3 |
|
|
use 5.008_001;
|
4 |
|
|
use strict;
|
5 |
|
|
use warnings;
|
6 |
|
|
|
7 |
|
|
my $have_xs;
|
8 |
|
|
our $VERSION = '0.430';
|
9 |
|
|
|
10 |
|
|
BEGIN
|
11 |
|
|
{
|
12 |
|
|
unless (defined($have_xs))
|
13 |
|
|
{
|
14 |
|
|
## no critic (ErrorHandling::RequireCheckingReturnValueOfEval)
|
15 |
|
|
eval { require List::MoreUtils::XS; } unless $ENV{LIST_MOREUTILS_PP};
|
16 |
|
|
## no critic (ErrorHandling::RequireCarping)
|
17 |
|
|
die $@ if $@ && defined $ENV{LIST_MOREUTILS_PP} && $ENV{LIST_MOREUTILS_PP} == 0;
|
18 |
|
|
$have_xs = 0 + defined($INC{'List/MoreUtils/XS.pm'});
|
19 |
|
|
}
|
20 |
|
|
|
21 |
|
|
use List::MoreUtils::PP qw();
|
22 |
|
|
}
|
23 |
|
|
|
24 |
|
|
use Exporter::Tiny qw();
|
25 |
|
|
|
26 |
|
|
my @junctions = qw(any all none notall);
|
27 |
|
|
my @v0_22 = qw(
|
28 |
|
|
true false
|
29 |
|
|
firstidx lastidx
|
30 |
|
|
insert_after insert_after_string
|
31 |
|
|
apply indexes
|
32 |
|
|
after after_incl before before_incl
|
33 |
|
|
firstval lastval
|
34 |
|
|
each_array each_arrayref
|
35 |
|
|
pairwise natatime
|
36 |
|
|
mesh uniq
|
37 |
|
|
minmax part
|
38 |
|
|
_XScompiled
|
39 |
|
|
);
|
40 |
|
|
my @v0_24 = qw(bsearch);
|
41 |
|
|
my @v0_33 = qw(sort_by nsort_by);
|
42 |
|
|
my @v0_400 = qw(one any_u all_u none_u notall_u one_u
|
43 |
|
|
firstres onlyidx onlyval onlyres lastres
|
44 |
|
|
singleton bsearchidx
|
45 |
|
|
);
|
46 |
|
|
my @v0_420 = qw(arrayify duplicates minmaxstr samples zip6 reduce_0 reduce_1 reduce_u
|
47 |
|
|
listcmp frequency occurrences mode
|
48 |
|
|
binsert bremove equal_range lower_bound upper_bound qsort
|
49 |
|
|
slide slideatatime);
|
50 |
|
|
|
51 |
|
|
my @all_functions = (@junctions, @v0_22, @v0_24, @v0_33, @v0_400, @v0_420);
|
52 |
|
|
|
53 |
|
|
## no critic (TestingAndDebugging::ProhibitNoStrict)
|
54 |
|
|
no strict "refs";
|
55 |
|
|
if ($have_xs)
|
56 |
|
|
{
|
57 |
|
|
my $x;
|
58 |
|
|
for (@all_functions)
|
59 |
|
|
{
|
60 |
|
|
List::MoreUtils->can($_) or *$_ = $x if ($x = List::MoreUtils::XS->can($_));
|
61 |
|
|
}
|
62 |
|
|
}
|
63 |
|
|
List::MoreUtils->can($_) or *$_ = List::MoreUtils::PP->can($_) for (@all_functions);
|
64 |
|
|
use strict;
|
65 |
|
|
## use critic (TestingAndDebugging::ProhibitNoStrict)
|
66 |
|
|
use parent qw(Exporter::Tiny);
|
67 |
|
|
|
68 |
|
|
my %alias_list = (
|
69 |
|
|
v0_22 => {
|
70 |
|
|
first_index => "firstidx",
|
71 |
|
|
last_index => "lastidx",
|
72 |
|
|
first_value => "firstval",
|
73 |
|
|
last_value => "lastval",
|
74 |
|
|
zip => "mesh",
|
75 |
|
|
},
|
76 |
|
|
v0_33 => {
|
77 |
|
|
distinct => "uniq",
|
78 |
|
|
},
|
79 |
|
|
v0_400 => {
|
80 |
|
|
first_result => "firstres",
|
81 |
|
|
only_index => "onlyidx",
|
82 |
|
|
only_value => "onlyval",
|
83 |
|
|
only_result => "onlyres",
|
84 |
|
|
last_result => "lastres",
|
85 |
|
|
bsearch_index => "bsearchidx",
|
86 |
|
|
},
|
87 |
|
|
v0_420 => {
|
88 |
|
|
bsearch_insert => "binsert",
|
89 |
|
|
bsearch_remove => "bremove",
|
90 |
|
|
zip_unflatten => "zip6",
|
91 |
|
|
},
|
92 |
|
|
);
|
93 |
|
|
|
94 |
|
|
our @EXPORT_OK = (@all_functions, map { keys %$_ } values %alias_list);
|
95 |
|
|
our %EXPORT_TAGS = (
|
96 |
|
|
all => \@EXPORT_OK,
|
97 |
|
|
'like_0.22' => [
|
98 |
|
|
any_u => {-as => 'any'},
|
99 |
|
|
all_u => {-as => 'all'},
|
100 |
|
|
none_u => {-as => 'none'},
|
101 |
|
|
notall_u => {-as => 'notall'},
|
102 |
|
|
@v0_22,
|
103 |
|
|
keys %{$alias_list{v0_22}},
|
104 |
|
|
],
|
105 |
|
|
'like_0.24' => [
|
106 |
|
|
any_u => {-as => 'any'},
|
107 |
|
|
all_u => {-as => 'all'},
|
108 |
|
|
notall_u => {-as => 'notall'},
|
109 |
|
|
'none',
|
110 |
|
|
@v0_22,
|
111 |
|
|
@v0_24,
|
112 |
|
|
keys %{$alias_list{v0_22}},
|
113 |
|
|
],
|
114 |
|
|
'like_0.33' => [
|
115 |
|
|
@junctions,
|
116 |
|
|
@v0_22,
|
117 |
|
|
# v0_24 functions were omitted
|
118 |
|
|
@v0_33,
|
119 |
|
|
keys %{$alias_list{v0_22}},
|
120 |
|
|
keys %{$alias_list{v0_33}},
|
121 |
|
|
],
|
122 |
|
|
);
|
123 |
|
|
|
124 |
|
|
for my $set (values %alias_list)
|
125 |
|
|
{
|
126 |
|
|
for my $alias (keys %$set)
|
127 |
|
|
{
|
128 |
|
|
## no critic (TestingAndDebugging::ProhibitNoStrict)
|
129 |
|
|
no strict qw(refs);
|
130 |
|
|
*$alias = __PACKAGE__->can($set->{$alias});
|
131 |
|
|
## use critic (TestingAndDebugging::ProhibitNoStrict)
|
132 |
|
|
}
|
133 |
|
|
}
|
134 |
|
|
use strict;
|
135 |
|
|
|
136 |
|
|
=pod
|
137 |
|
|
|
138 |
|
|
=head1 NAME
|
139 |
|
|
|
140 |
|
|
List::MoreUtils - Provide the stuff missing in List::Util
|
141 |
|
|
|
142 |
|
|
=head1 SYNOPSIS
|
143 |
|
|
|
144 |
|
|
# import specific functions
|
145 |
|
|
|
146 |
|
|
use List::MoreUtils qw(any uniq);
|
147 |
|
|
|
148 |
|
|
if ( any { /foo/ } uniq @has_duplicates ) {
|
149 |
|
|
# do stuff
|
150 |
|
|
}
|
151 |
|
|
|
152 |
|
|
# import everything
|
153 |
|
|
|
154 |
|
|
use List::MoreUtils ':all';
|
155 |
|
|
|
156 |
|
|
# import by API
|
157 |
|
|
|
158 |
|
|
# has "original" any/all/none/notall behavior
|
159 |
|
|
use List::MoreUtils ':like_0.22';
|
160 |
|
|
# 0.22 + bsearch
|
161 |
|
|
use List::MoreUtils ':like_0.24';
|
162 |
|
|
# has "simplified" any/all/none/notall behavior + (n)sort_by
|
163 |
|
|
use List::MoreUtils ':like_0.33';
|
164 |
|
|
|
165 |
|
|
=head1 DESCRIPTION
|
166 |
|
|
|
167 |
|
|
B<List::MoreUtils> provides some trivial but commonly needed functionality on
|
168 |
|
|
lists which is not going to go into L<List::Util>.
|
169 |
|
|
|
170 |
|
|
All of the below functions are implementable in only a couple of lines of Perl
|
171 |
|
|
code. Using the functions from this module however should give slightly better
|
172 |
|
|
performance as everything is implemented in C. The pure-Perl implementation of
|
173 |
|
|
these functions only serves as a fallback in case the C portions of this module
|
174 |
|
|
couldn't be compiled on this machine.
|
175 |
|
|
|
176 |
|
|
=head1 EXPORTS
|
177 |
|
|
|
178 |
|
|
=head2 Default behavior
|
179 |
|
|
|
180 |
|
|
Nothing by default. To import all of this module's symbols use the C<:all> tag.
|
181 |
|
|
Otherwise functions can be imported by name as usual:
|
182 |
|
|
|
183 |
|
|
use List::MoreUtils ':all';
|
184 |
|
|
|
185 |
|
|
use List::MoreUtils qw{ any firstidx };
|
186 |
|
|
|
187 |
|
|
Because historical changes to the API might make upgrading List::MoreUtils
|
188 |
|
|
difficult for some projects, the legacy API is available via special import
|
189 |
|
|
tags.
|
190 |
|
|
|
191 |
|
|
=head2 Like version 0.22 (last release with original API)
|
192 |
|
|
|
193 |
|
|
This API was available from 2006 to 2009, returning undef for empty lists on
|
194 |
|
|
C<all>/C<any>/C<none>/C<notall>:
|
195 |
|
|
|
196 |
|
|
use List::MoreUtils ':like_0.22';
|
197 |
|
|
|
198 |
|
|
This import tag will import all functions available as of version 0.22.
|
199 |
|
|
However, it will import C<any_u> as C<any>, C<all_u> as C<all>, C<none_u> as
|
200 |
|
|
C<none>, and C<notall_u> as C<notall>.
|
201 |
|
|
|
202 |
|
|
=head2 Like version 0.24 (first incompatible change)
|
203 |
|
|
|
204 |
|
|
This API was available from 2010 to 2011. It changed the return value of C<none>
|
205 |
|
|
and added the C<bsearch> function.
|
206 |
|
|
|
207 |
|
|
use List::MoreUtils ':like_0.24';
|
208 |
|
|
|
209 |
|
|
This import tag will import all functions available as of version 0.24.
|
210 |
|
|
However it will import C<any_u> as C<any>, C<all_u> as C<all>, and
|
211 |
|
|
C<notall_u> as C<notall>. It will import C<none> as described in
|
212 |
|
|
the documentation below (true for empty list).
|
213 |
|
|
|
214 |
|
|
=head2 Like version 0.33 (second incompatible change)
|
215 |
|
|
|
216 |
|
|
This API was available from 2011 to 2014. It is widely used in several CPAN
|
217 |
|
|
modules and thus it's closest to the current API. It changed the return values
|
218 |
|
|
of C<any>, C<all>, and C<notall>. It added the C<sort_by> and C<nsort_by> functions
|
219 |
|
|
and the C<distinct> alias for C<uniq>. It omitted C<bsearch>.
|
220 |
|
|
|
221 |
|
|
use List::MoreUtils ':like_0.33';
|
222 |
|
|
|
223 |
|
|
This import tag will import all functions available as of version 0.33. Note:
|
224 |
|
|
it will not import C<bsearch> for consistency with the 0.33 API.
|
225 |
|
|
|
226 |
|
|
=head1 FUNCTIONS
|
227 |
|
|
|
228 |
|
|
=head2 Junctions
|
229 |
|
|
|
230 |
|
|
=head3 I<Treatment of an empty list>
|
231 |
|
|
|
232 |
|
|
There are two schools of thought for how to evaluate a junction on an
|
233 |
|
|
empty list:
|
234 |
|
|
|
235 |
|
|
=over
|
236 |
|
|
|
237 |
|
|
=item *
|
238 |
|
|
|
239 |
|
|
Reduction to an identity (boolean)
|
240 |
|
|
|
241 |
|
|
=item *
|
242 |
|
|
|
243 |
|
|
Result is undefined (three-valued)
|
244 |
|
|
|
245 |
|
|
=back
|
246 |
|
|
|
247 |
|
|
In the first case, the result of the junction applied to the empty list is
|
248 |
|
|
determined by a mathematical reduction to an identity depending on whether
|
249 |
|
|
the underlying comparison is "or" or "and". Conceptually:
|
250 |
|
|
|
251 |
|
|
"any are true" "all are true"
|
252 |
|
|
-------------- --------------
|
253 |
|
|
2 elements: A || B || 0 A && B && 1
|
254 |
|
|
1 element: A || 0 A && 1
|
255 |
|
|
|
256 |
|
|
|
257 |
|
|
In the second case, three-value logic is desired, in which a junction
|
258 |
|
|
applied to an empty list returns C<undef> rather than true or false
|
259 |
|
|
|
260 |
|
|
Junctions with a C<_u> suffix implement three-valued logic. Those
|
261 |
|
|
without are boolean.
|
262 |
|
|
|
263 |
|
|
=head3 all BLOCK LIST
|
264 |
|
|
|
265 |
|
|
=head3 all_u BLOCK LIST
|
266 |
|
|
|
267 |
|
|
Returns a true value if all items in LIST meet the criterion given through
|
268 |
|
|
BLOCK. Sets C<$_> for each item in LIST in turn:
|
269 |
|
|
|
270 |
|
|
print "All values are non-negative"
|
271 |
|
|
if all { $_ >= 0 } ($x, $y, $z);
|
272 |
|
|
|
273 |
|
|
For an empty LIST, C<all> returns true (i.e. no values failed the condition)
|
274 |
|
|
and C<all_u> returns C<undef>.
|
275 |
|
|
|
276 |
|
|
Thus, C<< all_u(@list) >> is equivalent to C<< @list ? all(@list) : undef >>.
|
277 |
|
|
|
278 |
|
|
B<Note>: because Perl treats C<undef> as false, you must check the return value
|
279 |
|
|
of C<all_u> with C<defined> or you will get the opposite result of what you
|
280 |
|
|
expect.
|
281 |
|
|
|
282 |
|
|
=head3 any BLOCK LIST
|
283 |
|
|
|
284 |
|
|
=head3 any_u BLOCK LIST
|
285 |
|
|
|
286 |
|
|
Returns a true value if any item in LIST meets the criterion given through
|
287 |
|
|
BLOCK. Sets C<$_> for each item in LIST in turn:
|
288 |
|
|
|
289 |
|
|
print "At least one non-negative value"
|
290 |
|
|
if any { $_ >= 0 } ($x, $y, $z);
|
291 |
|
|
|
292 |
|
|
For an empty LIST, C<any> returns false and C<any_u> returns C<undef>.
|
293 |
|
|
|
294 |
|
|
Thus, C<< any_u(@list) >> is equivalent to C<< @list ? any(@list) : undef >>.
|
295 |
|
|
|
296 |
|
|
=head3 none BLOCK LIST
|
297 |
|
|
|
298 |
|
|
=head3 none_u BLOCK LIST
|
299 |
|
|
|
300 |
|
|
Logically the negation of C<any>. Returns a true value if no item in LIST meets
|
301 |
|
|
the criterion given through BLOCK. Sets C<$_> for each item in LIST in turn:
|
302 |
|
|
|
303 |
|
|
print "No non-negative values"
|
304 |
|
|
if none { $_ >= 0 } ($x, $y, $z);
|
305 |
|
|
|
306 |
|
|
For an empty LIST, C<none> returns true (i.e. no values failed the condition)
|
307 |
|
|
and C<none_u> returns C<undef>.
|
308 |
|
|
|
309 |
|
|
Thus, C<< none_u(@list) >> is equivalent to C<< @list ? none(@list) : undef >>.
|
310 |
|
|
|
311 |
|
|
B<Note>: because Perl treats C<undef> as false, you must check the return value
|
312 |
|
|
of C<none_u> with C<defined> or you will get the opposite result of what you
|
313 |
|
|
expect.
|
314 |
|
|
|
315 |
|
|
=head3 notall BLOCK LIST
|
316 |
|
|
|
317 |
|
|
=head3 notall_u BLOCK LIST
|
318 |
|
|
|
319 |
|
|
Logically the negation of C<all>. Returns a true value if not all items in LIST
|
320 |
|
|
meet the criterion given through BLOCK. Sets C<$_> for each item in LIST in
|
321 |
|
|
turn:
|
322 |
|
|
|
323 |
|
|
print "Not all values are non-negative"
|
324 |
|
|
if notall { $_ >= 0 } ($x, $y, $z);
|
325 |
|
|
|
326 |
|
|
For an empty LIST, C<notall> returns false and C<notall_u> returns C<undef>.
|
327 |
|
|
|
328 |
|
|
Thus, C<< notall_u(@list) >> is equivalent to C<< @list ? notall(@list) : undef >>.
|
329 |
|
|
|
330 |
|
|
=head3 one BLOCK LIST
|
331 |
|
|
|
332 |
|
|
=head3 one_u BLOCK LIST
|
333 |
|
|
|
334 |
|
|
Returns a true value if precisely one item in LIST meets the criterion
|
335 |
|
|
given through BLOCK. Sets C<$_> for each item in LIST in turn:
|
336 |
|
|
|
337 |
|
|
print "Precisely one value defined"
|
338 |
|
|
if one { defined($_) } @list;
|
339 |
|
|
|
340 |
|
|
Returns false otherwise.
|
341 |
|
|
|
342 |
|
|
For an empty LIST, C<one> returns false and C<one_u> returns C<undef>.
|
343 |
|
|
|
344 |
|
|
The expression C<one BLOCK LIST> is almost equivalent to
|
345 |
|
|
C<1 == true BLOCK LIST>, except for short-cutting.
|
346 |
|
|
Evaluation of BLOCK will immediately stop at the second true value.
|
347 |
|
|
|
348 |
|
|
=head2 Transformation
|
349 |
|
|
|
350 |
|
|
=head3 apply BLOCK LIST
|
351 |
|
|
|
352 |
|
|
Applies BLOCK to each item in LIST and returns a list of the values after BLOCK
|
353 |
|
|
has been applied. In scalar context, the last element is returned. This
|
354 |
|
|
function is similar to C<map> but will not modify the elements of the input
|
355 |
|
|
list:
|
356 |
|
|
|
357 |
|
|
my @list = (1 .. 4);
|
358 |
|
|
my @mult = apply { $_ *= 2 } @list;
|
359 |
|
|
print "\@list = @list\n";
|
360 |
|
|
print "\@mult = @mult\n";
|
361 |
|
|
__END__
|
362 |
|
|
@list = 1 2 3 4
|
363 |
|
|
@mult = 2 4 6 8
|
364 |
|
|
|
365 |
|
|
Think of it as syntactic sugar for
|
366 |
|
|
|
367 |
|
|
for (my @mult = @list) { $_ *= 2 }
|
368 |
|
|
|
369 |
|
|
=head3 insert_after BLOCK VALUE LIST
|
370 |
|
|
|
371 |
|
|
Inserts VALUE after the first item in LIST for which the criterion in BLOCK is
|
372 |
|
|
true. Sets C<$_> for each item in LIST in turn.
|
373 |
|
|
|
374 |
|
|
my @list = qw/This is a list/;
|
375 |
|
|
insert_after { $_ eq "a" } "longer" => @list;
|
376 |
|
|
print "@list";
|
377 |
|
|
__END__
|
378 |
|
|
This is a longer list
|
379 |
|
|
|
380 |
|
|
=head3 insert_after_string STRING VALUE LIST
|
381 |
|
|
|
382 |
|
|
Inserts VALUE after the first item in LIST which is equal to STRING.
|
383 |
|
|
|
384 |
|
|
my @list = qw/This is a list/;
|
385 |
|
|
insert_after_string "a", "longer" => @list;
|
386 |
|
|
print "@list";
|
387 |
|
|
__END__
|
388 |
|
|
This is a longer list
|
389 |
|
|
|
390 |
|
|
=head3 pairwise BLOCK ARRAY1 ARRAY2
|
391 |
|
|
|
392 |
|
|
Evaluates BLOCK for each pair of elements in ARRAY1 and ARRAY2 and returns a
|
393 |
|
|
new list consisting of BLOCK's return values. The two elements are set to C<$a>
|
394 |
|
|
and C<$b>. Note that those two are aliases to the original value so changing
|
395 |
|
|
them will modify the input arrays.
|
396 |
|
|
|
397 |
|
|
@a = (1 .. 5);
|
398 |
|
|
@b = (11 .. 15);
|
399 |
|
|
@x = pairwise { $a + $b } @a, @b; # returns 12, 14, 16, 18, 20
|
400 |
|
|
|
401 |
|
|
# mesh with pairwise
|
402 |
|
|
@a = qw/a b c/;
|
403 |
|
|
@b = qw/1 2 3/;
|
404 |
|
|
@x = pairwise { ($a, $b) } @a, @b; # returns a, 1, b, 2, c, 3
|
405 |
|
|
|
406 |
|
|
=head3 mesh ARRAY1 ARRAY2 [ ARRAY3 ... ]
|
407 |
|
|
|
408 |
|
|
=head3 zip ARRAY1 ARRAY2 [ ARRAY3 ... ]
|
409 |
|
|
|
410 |
|
|
Returns a list consisting of the first elements of each array, then
|
411 |
|
|
the second, then the third, etc, until all arrays are exhausted.
|
412 |
|
|
|
413 |
|
|
Examples:
|
414 |
|
|
|
415 |
|
|
@x = qw/a b c d/;
|
416 |
|
|
@y = qw/1 2 3 4/;
|
417 |
|
|
@z = mesh @x, @y; # returns a, 1, b, 2, c, 3, d, 4
|
418 |
|
|
|
419 |
|
|
@a = ('x');
|
420 |
|
|
@b = ('1', '2');
|
421 |
|
|
@c = qw/zip zap zot/;
|
422 |
|
|
@d = mesh @a, @b, @c; # x, 1, zip, undef, 2, zap, undef, undef, zot
|
423 |
|
|
|
424 |
|
|
C<zip> is an alias for C<mesh>.
|
425 |
|
|
|
426 |
|
|
=head3 zip6
|
427 |
|
|
|
428 |
|
|
=head3 zip_unflatten
|
429 |
|
|
|
430 |
|
|
Returns a list of arrays consisting of the first elements of each array,
|
431 |
|
|
then the second, then the third, etc, until all arrays are exhausted.
|
432 |
|
|
|
433 |
|
|
@x = qw/a b c d/;
|
434 |
|
|
@y = qw/1 2 3 4/;
|
435 |
|
|
@z = zip6 @x, @y; # returns [a, 1], [b, 2], [c, 3], [d, 4]
|
436 |
|
|
|
437 |
|
|
@a = ('x');
|
438 |
|
|
@b = ('1', '2');
|
439 |
|
|
@c = qw/zip zap zot/;
|
440 |
|
|
@d = zip6 @a, @b, @c; # [x, 1, zip], [undef, 2, zap], [undef, undef, zot]
|
441 |
|
|
|
442 |
|
|
C<zip_unflatten> is an alias for C<zip6>.
|
443 |
|
|
|
444 |
|
|
=head3 listcmp ARRAY0 ARRAY1 [ ARRAY2 ... ]
|
445 |
|
|
|
446 |
|
|
Returns an associative list of elements and every I<id> of the list it
|
447 |
|
|
was found in. Allows easy implementation of @a & @b, @a | @b, @a ^ @b and
|
448 |
|
|
so on.
|
449 |
|
|
Undefined entries in any given array are skipped.
|
450 |
|
|
|
451 |
|
|
my @a = qw(one two three four five six seven eight nine ten eleven twelve thirteen);
|
452 |
|
|
my @b = qw(two three five seven eleven thirteen seventeen);
|
453 |
|
|
my @c = qw(one one two three five eight thirteen twentyone);
|
454 |
|
|
my %cmp = listcmp @a, @b, @c; # returns (one => [0, 2], two => [0, 1, 2], three => [0, 1, 2], four => [0], ...)
|
455 |
|
|
|
456 |
|
|
my @seq = (1, 2, 3);
|
457 |
|
|
my @prim = (undef, 2, 3, 5);
|
458 |
|
|
my @fib = (1, 1, 2);
|
459 |
|
|
my %cmp = listcmp @seq, @prim, @fib;
|
460 |
|
|
# returns ( 1 => [0, 2], 2 => [0, 1, 2], 3 => [0, 1], 5 => [1] )
|
461 |
|
|
|
462 |
|
|
=head3 arrayify LIST[,LIST[,LIST...]]
|
463 |
|
|
|
464 |
|
|
Returns a list consisting of each element of given arrays. Recursive arrays
|
465 |
|
|
are flattened, too.
|
466 |
|
|
|
467 |
|
|
@a = (1, [[2], 3], 4, [5], 6, [7], 8, 9);
|
468 |
|
|
@l = arrayify @a; # returns 1, 2, 3, 4, 5, 6, 7, 8, 9
|
469 |
|
|
|
470 |
|
|
=head3 uniq LIST
|
471 |
|
|
|
472 |
|
|
=head3 distinct LIST
|
473 |
|
|
|
474 |
|
|
Returns a new list by stripping duplicate values in LIST by comparing
|
475 |
|
|
the values as hash keys, except that undef is considered separate from ''.
|
476 |
|
|
The order of elements in the returned list is the same as in LIST. In
|
477 |
|
|
scalar context, returns the number of unique elements in LIST.
|
478 |
|
|
|
479 |
|
|
my @x = uniq 1, 1, 2, 2, 3, 5, 3, 4; # returns 1 2 3 5 4
|
480 |
|
|
my $x = uniq 1, 1, 2, 2, 3, 5, 3, 4; # returns 5
|
481 |
|
|
# returns "Mike", "Michael", "Richard", "Rick"
|
482 |
|
|
my @n = distinct "Mike", "Michael", "Richard", "Rick", "Michael", "Rick"
|
483 |
|
|
# returns "A8", "", undef, "A5", "S1"
|
484 |
|
|
my @s = distinct "A8", "", undef, "A5", "S1", "A5", "A8"
|
485 |
|
|
# returns "Giulia", "Giulietta", undef, "", 156, "GTA", "GTV", 159, "Brera", "4C"
|
486 |
|
|
my @w = uniq "Giulia", "Giulietta", undef, "", 156, "GTA", "GTV", 159, "Brera", "4C", "Giulietta", "Giulia"
|
487 |
|
|
|
488 |
|
|
C<distinct> is an alias for C<uniq>.
|
489 |
|
|
|
490 |
|
|
B<RT#49800> can be used to give feedback about this behavior.
|
491 |
|
|
|
492 |
|
|
=head3 singleton LIST
|
493 |
|
|
|
494 |
|
|
Returns a new list by stripping values in LIST occurring more than once by
|
495 |
|
|
comparing the values as hash keys, except that undef is considered separate
|
496 |
|
|
from ''. The order of elements in the returned list is the same as in LIST.
|
497 |
|
|
In scalar context, returns the number of elements occurring only once in LIST.
|
498 |
|
|
|
499 |
|
|
my @x = singleton 1,1,2,2,3,4,5 # returns 3 4 5
|
500 |
|
|
|
501 |
|
|
=head3 duplicates LIST
|
502 |
|
|
|
503 |
|
|
Returns a new list by stripping values in LIST occurring less than twice by
|
504 |
|
|
comparing the values as hash keys, except that undef is considered separate
|
505 |
|
|
from ''. The order of elements in the returned list is the same as in LIST.
|
506 |
|
|
In scalar context, returns the number of elements occurring more than once
|
507 |
|
|
in LIST.
|
508 |
|
|
|
509 |
|
|
my @y = duplicates 1,1,2,4,7,2,3,4,6,9; #returns 1,2,4
|
510 |
|
|
|
511 |
|
|
=head3 frequency LIST
|
512 |
|
|
|
513 |
|
|
Returns an associative list of distinct values and the corresponding frequency.
|
514 |
|
|
|
515 |
|
|
my @f = frequency values %radio_nrw; # returns (
|
516 |
|
|
# 'Deutschlandfunk (DLF)' => 9, 'WDR 3' => 10,
|
517 |
|
|
# 'WDR 4' => 11, 'WDR 5' => 14, 'WDR Eins Live' => 14,
|
518 |
|
|
# 'Deutschlandradio Kultur' => 8,...)
|
519 |
|
|
|
520 |
|
|
=head3 occurrences LIST
|
521 |
|
|
|
522 |
|
|
Returns a new list of frequencies and the corresponding values from LIST.
|
523 |
|
|
|
524 |
|
|
my @o = occurrences ((1) x 3, (2) x 4, (3) x 2, (4) x 7, (5) x 2, (6) x 4);
|
525 |
|
|
# @o = (undef, undef, [3, 5], [1], [2, 6], undef, undef, [4]);
|
526 |
|
|
|
527 |
|
|
=head3 mode LIST
|
528 |
|
|
|
529 |
|
|
Returns the modal value of LIST. In scalar context, just the modal value
|
530 |
|
|
is returned, in list context all probes occurring I<modal> times are returned,
|
531 |
|
|
too.
|
532 |
|
|
|
533 |
|
|
my @m = mode ((1) x 3, (2) x 4, (3) x 2, (4) x 7, (5) x 2, (6) x 4, (7) x 3, (8) x 7);
|
534 |
|
|
# @m = (7, 4, 8) - bimodal LIST
|
535 |
|
|
|
536 |
|
|
=head3 slide BLOCK LIST
|
537 |
|
|
|
538 |
|
|
The function C<slide> operates on pairs of list elements like:
|
539 |
|
|
|
540 |
|
|
my @s = slide { "$a and $b" } (0..3);
|
541 |
|
|
# @s = ("0 and 1", "1 and 2", "2 and 3")
|
542 |
|
|
|
543 |
|
|
The idea behind this function is a kind of magnifying glass that is moved
|
544 |
|
|
along a list and calls C<BLOCK> every time the next list item is reached.
|
545 |
|
|
|
546 |
|
|
=head2 Partitioning
|
547 |
|
|
|
548 |
|
|
=head3 after BLOCK LIST
|
549 |
|
|
|
550 |
|
|
Returns a list of the values of LIST after (and not including) the point
|
551 |
|
|
where BLOCK returns a true value. Sets C<$_> for each element in LIST in turn.
|
552 |
|
|
|
553 |
|
|
@x = after { $_ % 5 == 0 } (1..9); # returns 6, 7, 8, 9
|
554 |
|
|
|
555 |
|
|
=head3 after_incl BLOCK LIST
|
556 |
|
|
|
557 |
|
|
Same as C<after> but also includes the element for which BLOCK is true.
|
558 |
|
|
|
559 |
|
|
=head3 before BLOCK LIST
|
560 |
|
|
|
561 |
|
|
Returns a list of values of LIST up to (and not including) the point where BLOCK
|
562 |
|
|
returns a true value. Sets C<$_> for each element in LIST in turn.
|
563 |
|
|
|
564 |
|
|
=head3 before_incl BLOCK LIST
|
565 |
|
|
|
566 |
|
|
Same as C<before> but also includes the element for which BLOCK is true.
|
567 |
|
|
|
568 |
|
|
=head3 part BLOCK LIST
|
569 |
|
|
|
570 |
|
|
Partitions LIST based on the return value of BLOCK which denotes into which
|
571 |
|
|
partition the current value is put.
|
572 |
|
|
|
573 |
|
|
Returns a list of the partitions thusly created. Each partition created is a
|
574 |
|
|
reference to an array.
|
575 |
|
|
|
576 |
|
|
my $i = 0;
|
577 |
|
|
my @part = part { $i++ % 2 } 1 .. 8; # returns [1, 3, 5, 7], [2, 4, 6, 8]
|
578 |
|
|
|
579 |
|
|
You can have a sparse list of partitions as well where non-set partitions will
|
580 |
|
|
be undef:
|
581 |
|
|
|
582 |
|
|
my @part = part { 2 } 1 .. 10; # returns undef, undef, [ 1 .. 10 ]
|
583 |
|
|
|
584 |
|
|
Be careful with negative values, though:
|
585 |
|
|
|
586 |
|
|
my @part = part { -1 } 1 .. 10;
|
587 |
|
|
__END__
|
588 |
|
|
Modification of non-creatable array value attempted, subscript -1 ...
|
589 |
|
|
|
590 |
|
|
Negative values are only ok when they refer to a partition previously created:
|
591 |
|
|
|
592 |
|
|
my @idx = ( 0, 1, -1 );
|
593 |
|
|
my $i = 0;
|
594 |
|
|
my @part = part { $idx[$i++ % 3] } 1 .. 8; # [1, 4, 7], [2, 3, 5, 6, 8]
|
595 |
|
|
|
596 |
|
|
=head3 samples COUNT LIST
|
597 |
|
|
|
598 |
|
|
Returns a new list containing COUNT random samples from LIST. Is similar to
|
599 |
|
|
L<List::Util/shuffle>, but stops after COUNT.
|
600 |
|
|
|
601 |
|
|
@r = samples 10, 1..10; # same as shuffle
|
602 |
|
|
@r2 = samples 5, 1..10; # gives 5 values from 1..10;
|
603 |
|
|
|
604 |
|
|
=head2 Iteration
|
605 |
|
|
|
606 |
|
|
=head3 each_array ARRAY1 ARRAY2 ...
|
607 |
|
|
|
608 |
|
|
Creates an array iterator to return the elements of the list of arrays ARRAY1,
|
609 |
|
|
ARRAY2 throughout ARRAYn in turn. That is, the first time it is called, it
|
610 |
|
|
returns the first element of each array. The next time, it returns the second
|
611 |
|
|
elements. And so on, until all elements are exhausted.
|
612 |
|
|
|
613 |
|
|
This is useful for looping over more than one array at once:
|
614 |
|
|
|
615 |
|
|
my $ea = each_array(@a, @b, @c);
|
616 |
|
|
while ( my ($a, $b, $c) = $ea->() ) { .... }
|
617 |
|
|
|
618 |
|
|
The iterator returns the empty list when it reached the end of all arrays.
|
619 |
|
|
|
620 |
|
|
If the iterator is passed an argument of 'C<index>', then it returns
|
621 |
|
|
the index of the last fetched set of values, as a scalar.
|
622 |
|
|
|
623 |
|
|
=head3 each_arrayref LIST
|
624 |
|
|
|
625 |
|
|
Like each_array, but the arguments are references to arrays, not the
|
626 |
|
|
plain arrays.
|
627 |
|
|
|
628 |
|
|
=head3 natatime EXPR, LIST
|
629 |
|
|
|
630 |
|
|
Creates an array iterator, for looping over an array in chunks of
|
631 |
|
|
C<$n> items at a time. (n at a time, get it?). An example is
|
632 |
|
|
probably a better explanation than I could give in words.
|
633 |
|
|
|
634 |
|
|
Example:
|
635 |
|
|
|
636 |
|
|
my @x = ('a' .. 'g');
|
637 |
|
|
my $it = natatime 3, @x;
|
638 |
|
|
while (my @vals = $it->())
|
639 |
|
|
{
|
640 |
|
|
print "@vals\n";
|
641 |
|
|
}
|
642 |
|
|
|
643 |
|
|
This prints
|
644 |
|
|
|
645 |
|
|
a b c
|
646 |
|
|
d e f
|
647 |
|
|
g
|
648 |
|
|
|
649 |
|
|
=head3 slideatatime STEP, WINDOW, LIST
|
650 |
|
|
|
651 |
|
|
Creates an array iterator, for looping over an array in chunks of
|
652 |
|
|
C<$windows-size> items at a time.
|
653 |
|
|
|
654 |
|
|
The idea behind this function is a kind of magnifying glass (finer
|
655 |
|
|
controllable compared to L</slide>) that is moved along a list.
|
656 |
|
|
|
657 |
|
|
Example:
|
658 |
|
|
|
659 |
|
|
my @x = ('a' .. 'g');
|
660 |
|
|
my $it = slideatatime 2, 3, @x;
|
661 |
|
|
while (my @vals = $it->())
|
662 |
|
|
{
|
663 |
|
|
print "@vals\n";
|
664 |
|
|
}
|
665 |
|
|
|
666 |
|
|
This prints
|
667 |
|
|
|
668 |
|
|
a b c
|
669 |
|
|
c d e
|
670 |
|
|
e f g
|
671 |
|
|
g
|
672 |
|
|
|
673 |
|
|
=head2 Searching
|
674 |
|
|
|
675 |
|
|
=head3 firstval BLOCK LIST
|
676 |
|
|
|
677 |
|
|
=head3 first_value BLOCK LIST
|
678 |
|
|
|
679 |
|
|
Returns the first element in LIST for which BLOCK evaluates to true. Each
|
680 |
|
|
element of LIST is set to C<$_> in turn. Returns C<undef> if no such element
|
681 |
|
|
has been found.
|
682 |
|
|
|
683 |
|
|
C<first_value> is an alias for C<firstval>.
|
684 |
|
|
|
685 |
|
|
=head3 onlyval BLOCK LIST
|
686 |
|
|
|
687 |
|
|
=head3 only_value BLOCK LIST
|
688 |
|
|
|
689 |
|
|
Returns the only element in LIST for which BLOCK evaluates to true. Sets
|
690 |
|
|
C<$_> for each item in LIST in turn. Returns C<undef> if no such element
|
691 |
|
|
has been found.
|
692 |
|
|
|
693 |
|
|
C<only_value> is an alias for C<onlyval>.
|
694 |
|
|
|
695 |
|
|
=head3 lastval BLOCK LIST
|
696 |
|
|
|
697 |
|
|
=head3 last_value BLOCK LIST
|
698 |
|
|
|
699 |
|
|
Returns the last value in LIST for which BLOCK evaluates to true. Each element
|
700 |
|
|
of LIST is set to C<$_> in turn. Returns C<undef> if no such element has been
|
701 |
|
|
found.
|
702 |
|
|
|
703 |
|
|
C<last_value> is an alias for C<lastval>.
|
704 |
|
|
|
705 |
|
|
=head3 firstres BLOCK LIST
|
706 |
|
|
|
707 |
|
|
=head3 first_result BLOCK LIST
|
708 |
|
|
|
709 |
|
|
Returns the result of BLOCK for the first element in LIST for which BLOCK
|
710 |
|
|
evaluates to true. Each element of LIST is set to C<$_> in turn. Returns
|
711 |
|
|
C<undef> if no such element has been found.
|
712 |
|
|
|
713 |
|
|
C<first_result> is an alias for C<firstres>.
|
714 |
|
|
|
715 |
|
|
=head3 onlyres BLOCK LIST
|
716 |
|
|
|
717 |
|
|
=head3 only_result BLOCK LIST
|
718 |
|
|
|
719 |
|
|
Returns the result of BLOCK for the first element in LIST for which BLOCK
|
720 |
|
|
evaluates to true. Sets C<$_> for each item in LIST in turn. Returns
|
721 |
|
|
C<undef> if no such element has been found.
|
722 |
|
|
|
723 |
|
|
C<only_result> is an alias for C<onlyres>.
|
724 |
|
|
|
725 |
|
|
=head3 lastres BLOCK LIST
|
726 |
|
|
|
727 |
|
|
=head3 last_result BLOCK LIST
|
728 |
|
|
|
729 |
|
|
Returns the result of BLOCK for the last element in LIST for which BLOCK
|
730 |
|
|
evaluates to true. Each element of LIST is set to C<$_> in turn. Returns
|
731 |
|
|
C<undef> if no such element has been found.
|
732 |
|
|
|
733 |
|
|
C<last_result> is an alias for C<lastres>.
|
734 |
|
|
|
735 |
|
|
=head3 indexes BLOCK LIST
|
736 |
|
|
|
737 |
|
|
Evaluates BLOCK for each element in LIST (assigned to C<$_>) and returns a list
|
738 |
|
|
of the indices of those elements for which BLOCK returned a true value. This is
|
739 |
|
|
just like C<grep> only that it returns indices instead of values:
|
740 |
|
|
|
741 |
|
|
@x = indexes { $_ % 2 == 0 } (1..10); # returns 1, 3, 5, 7, 9
|
742 |
|
|
|
743 |
|
|
=head3 firstidx BLOCK LIST
|
744 |
|
|
|
745 |
|
|
=head3 first_index BLOCK LIST
|
746 |
|
|
|
747 |
|
|
Returns the index of the first element in LIST for which the criterion in BLOCK
|
748 |
|
|
is true. Sets C<$_> for each item in LIST in turn:
|
749 |
|
|
|
750 |
|
|
my @list = (1, 4, 3, 2, 4, 6);
|
751 |
|
|
printf "item with index %i in list is 4", firstidx { $_ == 4 } @list;
|
752 |
|
|
__END__
|
753 |
|
|
item with index 1 in list is 4
|
754 |
|
|
|
755 |
|
|
Returns C<-1> if no such item could be found.
|
756 |
|
|
|
757 |
|
|
C<first_index> is an alias for C<firstidx>.
|
758 |
|
|
|
759 |
|
|
=head3 onlyidx BLOCK LIST
|
760 |
|
|
|
761 |
|
|
=head3 only_index BLOCK LIST
|
762 |
|
|
|
763 |
|
|
Returns the index of the only element in LIST for which the criterion
|
764 |
|
|
in BLOCK is true. Sets C<$_> for each item in LIST in turn:
|
765 |
|
|
|
766 |
|
|
my @list = (1, 3, 4, 3, 2, 4);
|
767 |
|
|
printf "uniqe index of item 2 in list is %i", onlyidx { $_ == 2 } @list;
|
768 |
|
|
__END__
|
769 |
|
|
unique index of item 2 in list is 4
|
770 |
|
|
|
771 |
|
|
Returns C<-1> if either no such item or more than one of these
|
772 |
|
|
has been found.
|
773 |
|
|
|
774 |
|
|
C<only_index> is an alias for C<onlyidx>.
|
775 |
|
|
|
776 |
|
|
=head3 lastidx BLOCK LIST
|
777 |
|
|
|
778 |
|
|
=head3 last_index BLOCK LIST
|
779 |
|
|
|
780 |
|
|
Returns the index of the last element in LIST for which the criterion in BLOCK
|
781 |
|
|
is true. Sets C<$_> for each item in LIST in turn:
|
782 |
|
|
|
783 |
|
|
my @list = (1, 4, 3, 2, 4, 6);
|
784 |
|
|
printf "item with index %i in list is 4", lastidx { $_ == 4 } @list;
|
785 |
|
|
__END__
|
786 |
|
|
item with index 4 in list is 4
|
787 |
|
|
|
788 |
|
|
Returns C<-1> if no such item could be found.
|
789 |
|
|
|
790 |
|
|
C<last_index> is an alias for C<lastidx>.
|
791 |
|
|
|
792 |
|
|
=head2 Sorting
|
793 |
|
|
|
794 |
|
|
=head3 sort_by BLOCK LIST
|
795 |
|
|
|
796 |
|
|
Returns the list of values sorted according to the string values returned by the
|
797 |
|
|
KEYFUNC block or function. A typical use of this may be to sort objects according
|
798 |
|
|
to the string value of some accessor, such as
|
799 |
|
|
|
800 |
|
|
sort_by { $_->name } @people
|
801 |
|
|
|
802 |
|
|
The key function is called in scalar context, being passed each value in turn as
|
803 |
|
|
both $_ and the only argument in the parameters, @_. The values are then sorted
|
804 |
|
|
according to string comparisons on the values returned.
|
805 |
|
|
This is equivalent to
|
806 |
|
|
|
807 |
|
|
sort { $a->name cmp $b->name } @people
|
808 |
|
|
|
809 |
|
|
except that it guarantees the name accessor will be executed only once per value.
|
810 |
|
|
One interesting use-case is to sort strings which may have numbers embedded in them
|
811 |
|
|
"naturally", rather than lexically.
|
812 |
|
|
|
813 |
|
|
sort_by { s/(\d+)/sprintf "%09d", $1/eg; $_ } @strings
|
814 |
|
|
|
815 |
|
|
This sorts strings by generating sort keys which zero-pad the embedded numbers to
|
816 |
|
|
some level (9 digits in this case), helping to ensure the lexical sort puts them
|
817 |
|
|
in the correct order.
|
818 |
|
|
|
819 |
|
|
=head3 nsort_by BLOCK LIST
|
820 |
|
|
|
821 |
|
|
Similar to sort_by but compares its key values numerically.
|
822 |
|
|
|
823 |
|
|
=head3 qsort BLOCK ARRAY
|
824 |
|
|
|
825 |
|
|
This sorts the given array B<in place> using the given compare code. Except for
|
826 |
|
|
tiny compare code like C<< $a <=> $b >>, qsort is much faster than Perl's C<sort>
|
827 |
|
|
depending on the version.
|
828 |
|
|
|
829 |
|
|
Compared 5.8 and 5.26:
|
830 |
|
|
|
831 |
|
|
my @rl;
|
832 |
|
|
for(my $i = 0; $i < 1E6; ++$i) { push @rl, rand(1E5) }
|
833 |
|
|
my $idx;
|
834 |
|
|
|
835 |
|
|
sub ext_cmp { $_[0] <=> $_[1] }
|
836 |
|
|
|
837 |
|
|
cmpthese( -60, {
|
838 |
|
|
'qsort' => sub {
|
839 |
|
|
my @qrl = @rl;
|
840 |
|
|
qsort { ext_cmp($a, $b) } @qrl;
|
841 |
|
|
$idx = bsearchidx { ext_cmp($_, $rl[0]) } @qrl
|
842 |
|
|
},
|
843 |
|
|
'reverse qsort' => sub {
|
844 |
|
|
my @qrl = @rl;
|
845 |
|
|
qsort { ext_cmp($b, $a) } @qrl;
|
846 |
|
|
$idx = bsearchidx { ext_cmp($rl[0], $_) } @qrl
|
847 |
|
|
},
|
848 |
|
|
'sort' => sub {
|
849 |
|
|
my @srl = @rl;
|
850 |
|
|
@srl = sort { ext_cmp($a, $b) } @srl;
|
851 |
|
|
$idx = bsearchidx { ext_cmp($_, $rl[0]) } @srl
|
852 |
|
|
},
|
853 |
|
|
'reverse sort' => sub {
|
854 |
|
|
my @srl = @rl;
|
855 |
|
|
@srl = sort { ext_cmp($b, $a) } @srl;
|
856 |
|
|
$idx = bsearchidx { ext_cmp($rl[0], $_) } @srl
|
857 |
|
|
},
|
858 |
|
|
});
|
859 |
|
|
|
860 |
|
|
5.8 results
|
861 |
|
|
|
862 |
|
|
s/iter reverse sort sort reverse qsort qsort
|
863 |
|
|
reverse sort 6.21 -- -0% -8% -10%
|
864 |
|
|
sort 6.19 0% -- -7% -10%
|
865 |
|
|
reverse qsort 5.73 8% 8% -- -2%
|
866 |
|
|
qsort 5.60 11% 11% 2% --
|
867 |
|
|
|
868 |
|
|
5.26 results
|
869 |
|
|
|
870 |
|
|
s/iter reverse sort sort reverse qsort qsort
|
871 |
|
|
reverse sort 4.54 -- -0% -96% -96%
|
872 |
|
|
sort 4.52 0% -- -96% -96%
|
873 |
|
|
reverse qsort 0.203 2139% 2131% -- -19%
|
874 |
|
|
qsort 0.164 2666% 2656% 24% --
|
875 |
|
|
|
876 |
|
|
Use it where external data sources might have to be compared (think of L<Unix::Statgrab>
|
877 |
|
|
"tables").
|
878 |
|
|
|
879 |
|
|
C<qsort> is available from List::MoreUtils::XS only. It's insane to maintain
|
880 |
|
|
a wrapper around Perl's sort nor having a pure Perl implementation. One could
|
881 |
|
|
create a flip-book in same speed as PP runs a qsort.
|
882 |
|
|
|
883 |
|
|
=head2 Searching in sorted Lists
|
884 |
|
|
|
885 |
|
|
=head3 bsearch BLOCK LIST
|
886 |
|
|
|
887 |
|
|
Performs a binary search on LIST which must be a sorted list of values. BLOCK
|
888 |
|
|
must return a negative value if the current element (stored in C<$_>) is smaller,
|
889 |
|
|
a positive value if it is bigger and zero if it matches.
|
890 |
|
|
|
891 |
|
|
Returns a boolean value in scalar context. In list context, it returns the element
|
892 |
|
|
if it was found, otherwise the empty list.
|
893 |
|
|
|
894 |
|
|
=head3 bsearchidx BLOCK LIST
|
895 |
|
|
|
896 |
|
|
=head3 bsearch_index BLOCK LIST
|
897 |
|
|
|
898 |
|
|
Performs a binary search on LIST which must be a sorted list of values. BLOCK
|
899 |
|
|
must return a negative value if the current element (stored in C<$_>) is smaller,
|
900 |
|
|
a positive value if it is bigger and zero if it matches.
|
901 |
|
|
|
902 |
|
|
Returns the index of found element, otherwise C<-1>.
|
903 |
|
|
|
904 |
|
|
C<bsearch_index> is an alias for C<bsearchidx>.
|
905 |
|
|
|
906 |
|
|
=head3 lower_bound BLOCK LIST
|
907 |
|
|
|
908 |
|
|
Returns the index of the first element in LIST which does not compare
|
909 |
|
|
I<less than val>. Technically it's the first element in LIST which does
|
910 |
|
|
not return a value below zero when passed to BLOCK.
|
911 |
|
|
|
912 |
|
|
@ids = (1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 11, 13, 13, 13, 17);
|
913 |
|
|
$lb = lower_bound { $_ <=> 2 } @ids; # returns 2
|
914 |
|
|
$lb = lower_bound { $_ <=> 4 } @ids; # returns 10
|
915 |
|
|
|
916 |
|
|
lower_bound has a complexity of O(log n).
|
917 |
|
|
|
918 |
|
|
=head3 upper_bound BLOCK LIST
|
919 |
|
|
|
920 |
|
|
Returns the index of the first element in LIST which does not compare
|
921 |
|
|
I<greater than val>. Technically it's the first element in LIST which does
|
922 |
|
|
not return a value below or equal to zero when passed to BLOCK.
|
923 |
|
|
|
924 |
|
|
@ids = (1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 11, 13, 13, 13, 17);
|
925 |
|
|
$lb = upper_bound { $_ <=> 2 } @ids; # returns 4
|
926 |
|
|
$lb = upper_bound { $_ <=> 4 } @ids; # returns 14
|
927 |
|
|
|
928 |
|
|
upper_bound has a complexity of O(log n).
|
929 |
|
|
|
930 |
|
|
=head3 equal_range BLOCK LIST
|
931 |
|
|
|
932 |
|
|
Returns a pair of indices containing the lower_bound and the upper_bound.
|
933 |
|
|
|
934 |
|
|
=head2 Operations on sorted Lists
|
935 |
|
|
|
936 |
|
|
=head3 binsert BLOCK ITEM LIST
|
937 |
|
|
|
938 |
|
|
=head3 bsearch_insert BLOCK ITEM LIST
|
939 |
|
|
|
940 |
|
|
Performs a binary search on LIST which must be a sorted list of values. BLOCK
|
941 |
|
|
must return a negative value if the current element (stored in C<$_>) is smaller,
|
942 |
|
|
a positive value if it is bigger and zero if it matches.
|
943 |
|
|
|
944 |
|
|
ITEM is inserted at the index where the ITEM should be placed (based on above
|
945 |
|
|
search). That means, it's inserted before the next bigger element.
|
946 |
|
|
|
947 |
|
|
@l = (2,3,5,7);
|
948 |
|
|
binsert { $_ <=> 4 } 4, @l; # @l = (2,3,4,5,7)
|
949 |
|
|
binsert { $_ <=> 6 } 42, @l; # @l = (2,3,4,42,7)
|
950 |
|
|
|
951 |
|
|
You take care that the inserted element matches the compare result.
|
952 |
|
|
|
953 |
|
|
=head3 bremove BLOCK LIST
|
954 |
|
|
|
955 |
|
|
=head3 bsearch_remove BLOCK LIST
|
956 |
|
|
|
957 |
|
|
Performs a binary search on LIST which must be a sorted list of values. BLOCK
|
958 |
|
|
must return a negative value if the current element (stored in C<$_>) is smaller,
|
959 |
|
|
a positive value if it is bigger and zero if it matches.
|
960 |
|
|
|
961 |
|
|
The item at the found position is removed and returned.
|
962 |
|
|
|
963 |
|
|
@l = (2,3,4,5,7);
|
964 |
|
|
bremove { $_ <=> 4 }, @l; # @l = (2,3,5,7);
|
965 |
|
|
|
966 |
|
|
=head2 Counting and calculation
|
967 |
|
|
|
968 |
|
|
=head3 true BLOCK LIST
|
969 |
|
|
|
970 |
|
|
Counts the number of elements in LIST for which the criterion in BLOCK is true.
|
971 |
|
|
Sets C<$_> for each item in LIST in turn:
|
972 |
|
|
|
973 |
|
|
printf "%i item(s) are defined", true { defined($_) } @list;
|
974 |
|
|
|
975 |
|
|
=head3 false BLOCK LIST
|
976 |
|
|
|
977 |
|
|
Counts the number of elements in LIST for which the criterion in BLOCK is false.
|
978 |
|
|
Sets C<$_> for each item in LIST in turn:
|
979 |
|
|
|
980 |
|
|
printf "%i item(s) are not defined", false { defined($_) } @list;
|
981 |
|
|
|
982 |
|
|
=head3 reduce_0 BLOCK LIST
|
983 |
|
|
|
984 |
|
|
Reduce LIST by calling BLOCK in scalar context for each element of LIST.
|
985 |
|
|
C<$a> contains the progressional result and is initialized with 0.
|
986 |
|
|
C<$b> contains the current processed element of LIST and C<$_> contains the
|
987 |
|
|
index of the element in C<$b>.
|
988 |
|
|
|
989 |
|
|
The idea behind reduce_0 is B<summation> (addition of a sequence of numbers).
|
990 |
|
|
|
991 |
|
|
=head3 reduce_1 BLOCK LIST
|
992 |
|
|
|
993 |
|
|
Reduce LIST by calling BLOCK in scalar context for each element of LIST.
|
994 |
|
|
C<$a> contains the progressional result and is initialized with 1.
|
995 |
|
|
C<$b> contains the current processed element of LIST and C<$_> contains the
|
996 |
|
|
index of the element in C<$b>.
|
997 |
|
|
|
998 |
|
|
The idea behind reduce_1 is product of a sequence of numbers.
|
999 |
|
|
|
1000 |
|
|
=head3 reduce_u BLOCK LIST
|
1001 |
|
|
|
1002 |
|
|
Reduce LIST by calling BLOCK in scalar context for each element of LIST.
|
1003 |
|
|
C<$a> contains the progressional result and is uninitialized.
|
1004 |
|
|
C<$b> contains the current processed element of LIST and C<$_> contains the
|
1005 |
|
|
index of the element in C<$b>.
|
1006 |
|
|
|
1007 |
|
|
This function has been added if one might need the extra of the index
|
1008 |
|
|
value but need an individual initialization.
|
1009 |
|
|
|
1010 |
|
|
B<Use with caution>: In most cases L<List::Util/reduce> will do the
|
1011 |
|
|
job better.
|
1012 |
|
|
|
1013 |
|
|
=head3 minmax LIST
|
1014 |
|
|
|
1015 |
|
|
Calculates the minimum and maximum of LIST and returns a two element list with
|
1016 |
|
|
the first element being the minimum and the second the maximum. Returns the
|
1017 |
|
|
empty list if LIST was empty.
|
1018 |
|
|
|
1019 |
|
|
The C<minmax> algorithm differs from a naive iteration over the list where each
|
1020 |
|
|
element is compared to two values being the so far calculated min and max value
|
1021 |
|
|
in that it only requires 3n/2 - 2 comparisons. Thus it is the most efficient
|
1022 |
|
|
possible algorithm.
|
1023 |
|
|
|
1024 |
|
|
However, the Perl implementation of it has some overhead simply due to the fact
|
1025 |
|
|
that there are more lines of Perl code involved. Therefore, LIST needs to be
|
1026 |
|
|
fairly big in order for C<minmax> to win over a naive implementation. This
|
1027 |
|
|
limitation does not apply to the XS version.
|
1028 |
|
|
|
1029 |
|
|
=head3 minmaxstr LIST
|
1030 |
|
|
|
1031 |
|
|
Computes the minimum and maximum of LIST using string compare and returns a
|
1032 |
|
|
two element list with the first element being the minimum and the second the
|
1033 |
|
|
maximum. Returns the empty list if LIST was empty.
|
1034 |
|
|
|
1035 |
|
|
The implementation is similar to C<minmax>.
|
1036 |
|
|
|
1037 |
|
|
=head1 ENVIRONMENT
|
1038 |
|
|
|
1039 |
|
|
When C<LIST_MOREUTILS_PP> is set, the module will always use the pure-Perl
|
1040 |
|
|
implementation and not the XS one. This environment variable is really just
|
1041 |
|
|
there for the test-suite to force testing the Perl implementation, and possibly
|
1042 |
|
|
for reporting of bugs. I don't see any reason to use it in a production
|
1043 |
|
|
environment.
|
1044 |
|
|
|
1045 |
|
|
=head1 MAINTENANCE
|
1046 |
|
|
|
1047 |
|
|
The maintenance goal is to preserve the documented semantics of the API;
|
1048 |
|
|
bug fixes that bring actual behavior in line with semantics are allowed.
|
1049 |
|
|
New API functions may be added over time. If a backwards incompatible
|
1050 |
|
|
change is unavoidable, we will attempt to provide support for the legacy
|
1051 |
|
|
API using the same export tag mechanism currently in place.
|
1052 |
|
|
|
1053 |
|
|
This module attempts to use few non-core dependencies. Non-core
|
1054 |
|
|
configuration and testing modules will be bundled when reasonable;
|
1055 |
|
|
run-time dependencies will be added only if they deliver substantial
|
1056 |
|
|
benefit.
|
1057 |
|
|
|
1058 |
|
|
=head1 CONTRIBUTING
|
1059 |
|
|
|
1060 |
|
|
While contributions are appreciated, a contribution should not cause more
|
1061 |
|
|
effort for the maintainer than the contribution itself saves (see
|
1062 |
|
|
L<Open Source Contribution Etiquette|http://tirania.org/blog/archive/2010/Dec-31.html>).
|
1063 |
|
|
|
1064 |
|
|
To get more familiar where help could be needed - see L<List::MoreUtils::Contributing>.
|
1065 |
|
|
|
1066 |
|
|
=head1 BUGS
|
1067 |
|
|
|
1068 |
|
|
There is a problem with a bug in 5.6.x perls. It is a syntax error to write
|
1069 |
|
|
things like:
|
1070 |
|
|
|
1071 |
|
|
my @x = apply { s/foo/bar/ } qw{ foo bar baz };
|
1072 |
|
|
|
1073 |
|
|
It has to be written as either
|
1074 |
|
|
|
1075 |
|
|
my @x = apply { s/foo/bar/ } 'foo', 'bar', 'baz';
|
1076 |
|
|
|
1077 |
|
|
or
|
1078 |
|
|
|
1079 |
|
|
my @x = apply { s/foo/bar/ } my @dummy = qw/foo bar baz/;
|
1080 |
|
|
|
1081 |
|
|
Perl 5.5.x and Perl 5.8.x don't suffer from this limitation.
|
1082 |
|
|
|
1083 |
|
|
If you have a functionality that you could imagine being in this module, please
|
1084 |
|
|
drop me a line. This module's policy will be less strict than L<List::Util>'s
|
1085 |
|
|
when it comes to additions as it isn't a core module.
|
1086 |
|
|
|
1087 |
|
|
When you report bugs, it would be nice if you could additionally give me the
|
1088 |
|
|
output of your program with the environment variable C<LIST_MOREUTILS_PP> set
|
1089 |
|
|
to a true value. That way I know where to look for the problem (in XS,
|
1090 |
|
|
pure-Perl or possibly both).
|
1091 |
|
|
|
1092 |
|
|
=head1 SUPPORT
|
1093 |
|
|
|
1094 |
|
|
Bugs should always be submitted via the CPAN bug tracker.
|
1095 |
|
|
|
1096 |
|
|
You can find documentation for this module with the perldoc command.
|
1097 |
|
|
|
1098 |
|
|
perldoc List::MoreUtils
|
1099 |
|
|
|
1100 |
|
|
You can also look for information at:
|
1101 |
|
|
|
1102 |
|
|
=over 4
|
1103 |
|
|
|
1104 |
|
|
=item * RT: CPAN's request tracker
|
1105 |
|
|
|
1106 |
|
|
L<https://rt.cpan.org/Dist/Display.html?Name=List-MoreUtils>
|
1107 |
|
|
|
1108 |
|
|
=item * AnnoCPAN: Annotated CPAN documentation
|
1109 |
|
|
|
1110 |
|
|
L<http://annocpan.org/dist/List-MoreUtils>
|
1111 |
|
|
|
1112 |
|
|
=item * CPAN Ratings
|
1113 |
|
|
|
1114 |
|
|
L<http://cpanratings.perl.org/dist/List-MoreUtils>
|
1115 |
|
|
|
1116 |
|
|
=item * MetaCPAN
|
1117 |
|
|
|
1118 |
|
|
L<https://metacpan.org/release/List-MoreUtils>
|
1119 |
|
|
|
1120 |
|
|
=item * CPAN Search
|
1121 |
|
|
|
1122 |
|
|
L<http://search.cpan.org/dist/List-MoreUtils/>
|
1123 |
|
|
|
1124 |
|
|
=item * Git Repository
|
1125 |
|
|
|
1126 |
|
|
L<https://github.com/perl5-utils/List-MoreUtils>
|
1127 |
|
|
|
1128 |
|
|
=back
|
1129 |
|
|
|
1130 |
|
|
=head2 Where can I go for help?
|
1131 |
|
|
|
1132 |
|
|
If you have a bug report, a patch or a suggestion, please open a new
|
1133 |
|
|
report ticket at CPAN (but please check previous reports first in case
|
1134 |
|
|
your issue has already been addressed) or open an issue on GitHub.
|
1135 |
|
|
|
1136 |
|
|
Report tickets should contain a detailed description of the bug or
|
1137 |
|
|
enhancement request and at least an easily verifiable way of
|
1138 |
|
|
reproducing the issue or fix. Patches are always welcome, too - and
|
1139 |
|
|
it's cheap to send pull-requests on GitHub. Please keep in mind that
|
1140 |
|
|
code changes are more likely accepted when they're bundled with an
|
1141 |
|
|
approving test.
|
1142 |
|
|
|
1143 |
|
|
If you think you've found a bug then please read
|
1144 |
|
|
"How to Report Bugs Effectively" by Simon Tatham:
|
1145 |
|
|
L<http://www.chiark.greenend.org.uk/~sgtatham/bugs.html>.
|
1146 |
|
|
|
1147 |
|
|
=head2 Where can I go for help with a concrete version?
|
1148 |
|
|
|
1149 |
|
|
Bugs and feature requests are accepted against the latest version
|
1150 |
|
|
only. To get patches for earlier versions, you need to get an
|
1151 |
|
|
agreement with a developer of your choice - who may or not report the
|
1152 |
|
|
issue and a suggested fix upstream (depends on the license you have
|
1153 |
|
|
chosen).
|
1154 |
|
|
|
1155 |
|
|
=head2 Business support and maintenance
|
1156 |
|
|
|
1157 |
|
|
Generally, in volunteered projects, there is no right for support.
|
1158 |
|
|
While every maintainer is happy to improve the provided software,
|
1159 |
|
|
spare time is limited.
|
1160 |
|
|
|
1161 |
|
|
For those who have a use case which requires guaranteed support, one of
|
1162 |
|
|
the maintainers should be hired or contracted. For business support you
|
1163 |
|
|
can contact Jens via his CPAN email address rehsackATcpan.org. Please
|
1164 |
|
|
keep in mind that business support is neither available for free nor
|
1165 |
|
|
are you eligible to receive any support based on the license distributed
|
1166 |
|
|
with this package.
|
1167 |
|
|
|
1168 |
|
|
=head1 THANKS
|
1169 |
|
|
|
1170 |
|
|
=head2 Tassilo von Parseval
|
1171 |
|
|
|
1172 |
|
|
Credits go to a number of people: Steve Purkis for giving me namespace advice
|
1173 |
|
|
and James Keenan and Terrence Branno for their effort of keeping the CPAN
|
1174 |
|
|
tidier by making L<List::Utils> obsolete.
|
1175 |
|
|
|
1176 |
|
|
Brian McCauley suggested the inclusion of apply() and provided the pure-Perl
|
1177 |
|
|
implementation for it.
|
1178 |
|
|
|
1179 |
|
|
Eric J. Roode asked me to add all functions from his module C<List::MoreUtil>
|
1180 |
|
|
into this one. With minor modifications, the pure-Perl implementations of those
|
1181 |
|
|
are by him.
|
1182 |
|
|
|
1183 |
|
|
The bunch of people who almost immediately pointed out the many problems with
|
1184 |
|
|
the glitchy 0.07 release (Slaven Rezic, Ron Savage, CPAN testers).
|
1185 |
|
|
|
1186 |
|
|
A particularly nasty memory leak was spotted by Thomas A. Lowery.
|
1187 |
|
|
|
1188 |
|
|
Lars Thegler made me aware of problems with older Perl versions.
|
1189 |
|
|
|
1190 |
|
|
Anno Siegel de-orphaned each_arrayref().
|
1191 |
|
|
|
1192 |
|
|
David Filmer made me aware of a problem in each_arrayref that could ultimately
|
1193 |
|
|
lead to a segfault.
|
1194 |
|
|
|
1195 |
|
|
Ricardo Signes suggested the inclusion of part() and provided the
|
1196 |
|
|
Perl-implementation.
|
1197 |
|
|
|
1198 |
|
|
Robin Huston kindly fixed a bug in perl's MULTICALL API to make the
|
1199 |
|
|
XS-implementation of part() work.
|
1200 |
|
|
|
1201 |
|
|
=head2 Jens Rehsack
|
1202 |
|
|
|
1203 |
|
|
Credits goes to all people contributing feedback during the v0.400
|
1204 |
|
|
development releases.
|
1205 |
|
|
|
1206 |
|
|
Special thanks goes to David Golden who spent a lot of effort to develop
|
1207 |
|
|
a design to support current state of CPAN as well as ancient software
|
1208 |
|
|
somewhere in the dark. He also contributed a lot of patches to refactor
|
1209 |
|
|
the API frontend to welcome any user of List::MoreUtils - from ancient
|
1210 |
|
|
past to recently last used.
|
1211 |
|
|
|
1212 |
|
|
Toby Inkster provided a lot of useful feedback for sane importer code
|
1213 |
|
|
and was a nice sounding board for API discussions.
|
1214 |
|
|
|
1215 |
|
|
Peter Rabbitson provided a sane git repository setup containing entire
|
1216 |
|
|
package history.
|
1217 |
|
|
|
1218 |
|
|
=head1 TODO
|
1219 |
|
|
|
1220 |
|
|
A pile of requests from other people is still pending further processing in
|
1221 |
|
|
my mailbox. This includes:
|
1222 |
|
|
|
1223 |
|
|
=over 4
|
1224 |
|
|
|
1225 |
|
|
=item * delete_index
|
1226 |
|
|
|
1227 |
|
|
=item * random_item
|
1228 |
|
|
|
1229 |
|
|
=item * random_item_delete_index
|
1230 |
|
|
|
1231 |
|
|
=item * list_diff_hash
|
1232 |
|
|
|
1233 |
|
|
=item * list_diff_inboth
|
1234 |
|
|
|
1235 |
|
|
=item * list_diff_infirst
|
1236 |
|
|
|
1237 |
|
|
=item * list_diff_insecond
|
1238 |
|
|
|
1239 |
|
|
These were all suggested by Dan Muey.
|
1240 |
|
|
|
1241 |
|
|
=item * listify
|
1242 |
|
|
|
1243 |
|
|
Always return a flat list when either a simple scalar value was passed or an
|
1244 |
|
|
array-reference. Suggested by Mark Summersault.
|
1245 |
|
|
|
1246 |
|
|
=back
|
1247 |
|
|
|
1248 |
|
|
=head1 SEE ALSO
|
1249 |
|
|
|
1250 |
|
|
L<List::Util>, L<List::AllUtils>, L<List::UtilsBy>
|
1251 |
|
|
|
1252 |
|
|
=head1 AUTHOR
|
1253 |
|
|
|
1254 |
|
|
Jens Rehsack E<lt>rehsack AT cpan.orgE<gt>
|
1255 |
|
|
|
1256 |
|
|
Adam Kennedy E<lt>adamk@cpan.orgE<gt>
|
1257 |
|
|
|
1258 |
|
|
Tassilo von Parseval E<lt>tassilo.von.parseval@rwth-aachen.deE<gt>
|
1259 |
|
|
|
1260 |
|
|
=head1 COPYRIGHT AND LICENSE
|
1261 |
|
|
|
1262 |
|
|
Some parts copyright 2011 Aaron Crane.
|
1263 |
|
|
|
1264 |
|
|
Copyright 2004 - 2010 by Tassilo von Parseval
|
1265 |
|
|
|
1266 |
|
|
Copyright 2013 - 2017 by Jens Rehsack
|
1267 |
|
|
|
1268 |
|
|
All code added with 0.417 or later is licensed under the Apache License,
|
1269 |
|
|
Version 2.0 (the "License"); you may not use this file except in compliance
|
1270 |
|
|
with the License. You may obtain a copy of the License at
|
1271 |
|
|
|
1272 |
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
1273 |
|
|
|
1274 |
|
|
Unless required by applicable law or agreed to in writing, software
|
1275 |
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
1276 |
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1277 |
|
|
See the License for the specific language governing permissions and
|
1278 |
|
|
limitations under the License.
|
1279 |
|
|
|
1280 |
|
|
All code until 0.416 is licensed under the same terms as Perl itself,
|
1281 |
|
|
either Perl version 5.8.4 or, at your option, any later version of
|
1282 |
|
|
Perl 5 you may have available.
|
1283 |
|
|
|
1284 |
|
|
=cut
|
1285 |
|
|
|
1286 |
|
|
1;
|