1NAME
2
3 List::UtilsBy - higher-order list utility functions
4
5SYNOPSIS
6
7 use List::UtilsBy qw( nsort_by min_by );
8
9 use File::stat qw( stat );
10 my @files_by_age = nsort_by { stat($_)->mtime } @files;
11
12 my $shortest_name = min_by { length } @names;
13
14DESCRIPTION
15
16 This module provides a number of list utility functions, all of which
17 take an initial code block to control their behaviour. They are
18 variations on similar core perl or List::Util functions of similar
19 names, but which use the block to control their behaviour. For example,
20 the core Perl function sort takes a list of values and returns them,
21 sorted into order by their string value. The "sort_by" function sorts
22 them according to the string value returned by the extra function, when
23 given each value.
24
25 my @names_sorted = sort @names;
26
27 my @people_sorted = sort_by { $_->name } @people;
28
29FUNCTIONS
30
31 All functions added since version 0.04 unless otherwise stated, as the
32 original names for earlier versions were renamed.
33
34 sort_by
35
36 @vals = sort_by { KEYFUNC } @vals
37
38 Returns the list of values sorted according to the string values
39 returned by the KEYFUNC block or function. A typical use of this may be
40 to sort objects according to the string value of some accessor, such as
41
42 sort_by { $_->name } @people
43
44 The key function is called in scalar context, being passed each value
45 in turn as both $_ and the only argument in the parameters, @_. The
46 values are then sorted according to string comparisons on the values
47 returned.
48
49 This is equivalent to
50
51 sort { $a->name cmp $b->name } @people
52
53 except that it guarantees the name accessor will be executed only once
54 per value.
55
56 One interesting use-case is to sort strings which may have numbers
57 embedded in them "naturally", rather than lexically.
58
59 sort_by { s/(\d+)/sprintf "%09d", $1/eg; $_ } @strings
60
61 This sorts strings by generating sort keys which zero-pad the embedded
62 numbers to some level (9 digits in this case), helping to ensure the
63 lexical sort puts them in the correct order.
64
65 nsort_by
66
67 @vals = nsort_by { KEYFUNC } @vals
68
69 Similar to "sort_by" but compares its key values numerically.
70
71 rev_sort_by
72
73 rev_nsort_by
74
75 @vals = rev_sort_by { KEYFUNC } @vals
76
77 @vals = rev_nsort_by { KEYFUNC } @vals
78
79 Since version 0.06.
80
81 Similar to "sort_by" and "nsort_by" but returns the list in the reverse
82 order. Equivalent to
83
84 @vals = reverse sort_by { KEYFUNC } @vals
85
86 except that these functions are slightly more efficient because they
87 avoid the final reverse operation.
88
89 max_by
90
91 $optimal = max_by { KEYFUNC } @vals
92
93 @optimal = max_by { KEYFUNC } @vals
94
95 Returns the (first) value from @vals that gives the numerically largest
96 result from the key function.
97
98 my $tallest = max_by { $_->height } @people
99
100 use File::stat qw( stat );
101 my $newest = max_by { stat($_)->mtime } @files;
102
103 In scalar context, the first maximal value is returned. In list
104 context, a list of all the maximal values is returned. This may be used
105 to obtain positions other than the first, if order is significant.
106
107 If called on an empty list, an empty list is returned.
108
109 For symmetry with the "nsort_by" function, this is also provided under
110 the name nmax_by since it behaves numerically.
111
112 min_by
113
114 $optimal = min_by { KEYFUNC } @vals
115
116 @optimal = min_by { KEYFUNC } @vals
117
118 Similar to "max_by" but returns values which give the numerically
119 smallest result from the key function. Also provided as nmin_by
120
121 minmax_by
122
123 ( $minimal, $maximal ) = minmax_by { KEYFUNC } @vals
124
125 Since version 0.11.
126
127 Similar to calling both "min_by" and "max_by" with the same key
128 function on the same list. This version is more efficient than calling
129 the two other functions individually, as it has less work to perform
130 overall. In the case of ties, only the first optimal element found in
131 each case is returned. Also provided as nminmax_by.
132
133 uniq_by
134
135 @vals = uniq_by { KEYFUNC } @vals
136
137 Returns a list of the subset of values for which the key function block
138 returns unique values. The first value yielding a particular key is
139 chosen, subsequent values are rejected.
140
141 my @some_fruit = uniq_by { $_->colour } @fruit;
142
143 To select instead the last value per key, reverse the input list. If
144 the order of the results is significant, don't forget to reverse the
145 result as well:
146
147 my @some_fruit = reverse uniq_by { $_->colour } reverse @fruit;
148
149 Because the values returned by the key function are used as hash keys,
150 they ought to either be strings, or at least well-behaved as strings
151 (such as numbers, or object references which overload stringification
152 in a suitable manner).
153
154 partition_by
155
156 %parts = partition_by { KEYFUNC } @vals
157
158 Returns a key/value list of ARRAY refs containing all the original
159 values distributed according to the result of the key function block.
160 Each value will be an ARRAY ref containing all the values which
161 returned the string from the key function, in their original order.
162
163 my %balls_by_colour = partition_by { $_->colour } @balls;
164
165 Because the values returned by the key function are used as hash keys,
166 they ought to either be strings, or at least well-behaved as strings
167 (such as numbers, or object references which overload stringification
168 in a suitable manner).
169
170 count_by
171
172 %counts = count_by { KEYFUNC } @vals
173
174 Since version 0.07.
175
176 Returns a key/value list of integers, giving the number of times the
177 key function block returned the key, for each value in the list.
178
179 my %count_of_balls = count_by { $_->colour } @balls;
180
181 Because the values returned by the key function are used as hash keys,
182 they ought to either be strings, or at least well-behaved as strings
183 (such as numbers, or object references which overload stringification
184 in a suitable manner).
185
186 zip_by
187
188 @vals = zip_by { ITEMFUNC } \@arr0, \@arr1, \@arr2,...
189
190 Returns a list of each of the values returned by the function block,
191 when invoked with values from across each each of the given ARRAY
192 references. Each value in the returned list will be the result of the
193 function having been invoked with arguments at that position, from
194 across each of the arrays given.
195
196 my @transposition = zip_by { [ @_ ] } @matrix;
197
198 my @names = zip_by { "$_[1], $_[0]" } \@firstnames, \@surnames;
199
200 print zip_by { "$_[0] => $_[1]\n" } [ keys %hash ], [ values %hash ];
201
202 If some of the arrays are shorter than others, the function will behave
203 as if they had undef in the trailing positions. The following two lines
204 are equivalent:
205
206 zip_by { f(@_) } [ 1, 2, 3 ], [ "a", "b" ]
207 f( 1, "a" ), f( 2, "b" ), f( 3, undef )
208
209 The item function is called by map, so if it returns a list, the entire
210 list is included in the result. This can be useful for example, for
211 generating a hash from two separate lists of keys and values
212
213 my %nums = zip_by { @_ } [qw( one two three )], [ 1, 2, 3 ];
214 # %nums = ( one => 1, two => 2, three => 3 )
215
216 (A function having this behaviour is sometimes called zipWith, e.g. in
217 Haskell, but that name would not fit the naming scheme used by this
218 module).
219
220 unzip_by
221
222 $arr0, $arr1, $arr2, ... = unzip_by { ITEMFUNC } @vals
223
224 Since version 0.09.
225
226 Returns a list of ARRAY references containing the values returned by
227 the function block, when invoked for each of the values given in the
228 input list. Each of the returned ARRAY references will contain the
229 values returned at that corresponding position by the function block.
230 That is, the first returned ARRAY reference will contain all the values
231 returned in the first position by the function block, the second will
232 contain all the values from the second position, and so on.
233
234 my ( $firstnames, $lastnames ) = unzip_by { m/^(.*?) (.*)$/ } @names;
235
236 If the function returns lists of differing lengths, the result will be
237 padded with undef in the missing elements.
238
239 This function is an inverse of "zip_by", if given a corresponding
240 inverse function.
241
242 extract_by
243
244 @vals = extract_by { SELECTFUNC } @arr
245
246 Since version 0.05.
247
248 Removes elements from the referenced array on which the selection
249 function returns true, and returns a list containing those elements.
250 This function is similar to grep, except that it modifies the
251 referenced array to remove the selected values from it, leaving only
252 the unselected ones.
253
254 my @red_balls = extract_by { $_->color eq "red" } @balls;
255
256 # Now there are no red balls in the @balls array
257
258 This function modifies a real array, unlike most of the other functions
259 in this module. Because of this, it requires a real array, not just a
260 list.
261
262 This function is implemented by invoking splice on the array, not by
263 constructing a new list and assigning it. One result of this is that
264 weak references will not be disturbed.
265
266 extract_by { !defined $_ } @refs;
267
268 will leave weak references weakened in the @refs array, whereas
269
270 @refs = grep { defined $_ } @refs;
271
272 will strengthen them all again.
273
274 extract_first_by
275
276 $val = extract_first_by { SELECTFUNC } @arr
277
278 Since version 0.10.
279
280 A hybrid between "extract_by" and List::Util::first. Removes the first
281 element from the referenced array on which the selection function
282 returns true, returning it.
283
284 As with "extract_by", this function requires a real array and not just
285 a list, and is also implemented using splice so that weak references
286 are not disturbed.
287
288 If this function fails to find a matching element, it will return an
289 empty list in list context. This allows a caller to distinguish the
290 case between no matching element, and the first matching element being
291 undef.
292
293 weighted_shuffle_by
294
295 @vals = weighted_shuffle_by { WEIGHTFUNC } @vals
296
297 Since version 0.07.
298
299 Returns the list of values shuffled into a random order. The
300 randomisation is not uniform, but weighted by the value returned by the
301 WEIGHTFUNC. The probabilty of each item being returned first will be
302 distributed with the distribution of the weights, and so on recursively
303 for the remaining items.
304
305 bundle_by
306
307 @vals = bundle_by { BLOCKFUNC } $number, @vals
308
309 Since version 0.07.
310
311 Similar to a regular map functional, returns a list of the values
312 returned by BLOCKFUNC. Values from the input list are given to the
313 block function in bundles of $number.
314
315 If given a list of values whose length does not evenly divide by
316 $number, the final call will be passed fewer elements than the others.
317
318TODO
319
320 * XS implementations
321
322 These functions are currently all written in pure perl. Some at
323 least, may benefit from having XS implementations to speed up their
324 logic.
325
326 * Merge into List::Util or List::MoreUtils
327
328 This module shouldn't really exist. The functions should instead be
329 part of one of the existing modules that already contain many list
330 utility functions. Having Yet Another List Utilty Module just worsens
331 the problem.
332
333 I have attempted to contact the authors of both of the above modules,
334 to no avail; therefore I decided it best to write and release this
335 code here anyway so that it is at least on CPAN. Once there, we can
336 then see how best to merge it into an existing module.
337
338 Updated 2015/07/16: As I am now the maintainer of List::Util, some
339 amount of merging/copying should be possible. However, given the
340 latter's key position in the core perl distribution and head of the
341 "CPAN River" I am keen not to do this wholesale, but a selected pick
342 of what seems best, by a popular consensus.
343
344 * head and tail-like functions
345
346 Consider perhaps
347
348 head_before { COND } LIST # excludes terminating element
349 head_upto { COND } LIST # includes terminating element
350
351 tail_since { COND } LIST # includes initiating element
352 tail_after { COND } LIST # excludes initiating element
353
354 (See also https://rt.cpan.org/Ticket/Display.html?id=105907).
355
356AUTHOR
357
358 Paul Evans <leonerd@leonerd.org.uk>
359
360