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