Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
List::UtilsBy(3)      User Contributed Perl Documentation     List::UtilsBy(3)

NAME
       "List::UtilsBy" - higher-order list utility functions

SYNOPSIS
	  use List::UtilsBy qw(	nsort_by min_by	);

	  use File::stat qw( stat );
	  my @files_by_age = nsort_by {	stat($_)->mtime	} @files;

	  my $shortest_name = min_by { length }	@names;

DESCRIPTION
       This module provides a number of	list utility functions,	all of which
       take an initial code block to control their behaviour. They are
       variations on similar core perl or "List::Util" functions of similar
       names, but which	use the	block to control their behaviour. For example,
       the core	Perl function "sort" takes a list of values and	returns	them,
       sorted into order by their string value.	 The "sort_by" function	sorts
       them according to the string value returned by the extra	function, when
       given each value.

	  my @names_sorted = sort @names;

	  my @people_sorted = sort_by {	$_->name } @people;

FUNCTIONS
       All functions added since version 0.04 unless otherwise stated, as the
       original	names for earlier versions were	renamed.

   sort_by
	  @vals	= sort_by { KEYFUNC } @vals

       Returns the list	of values sorted according to the string values
       returned	by the "KEYFUNC" block or function. A typical use of this may
       be to sort objects according to the string value	of some	accessor, such
       as

	  sort_by { $_->name } @people

       The key function	is called in scalar context, being passed each value
       in turn as both $_ and the only argument	in the parameters, @_. The
       values are then sorted according	to string comparisons on the values
       returned.

       This is equivalent to

	  sort { $a->name cmp $b->name } @people

       except that it guarantees the "name" accessor will be executed only
       once per	value.

       One interesting use-case	is to sort strings which may have numbers
       embedded	in them	"naturally", rather than lexically.

	  sort_by { s/(\d+)/sprintf "%09d", $1/eg; $_ }	@strings

       This sorts strings by generating	sort keys which	zero-pad the embedded
       numbers to some level (9	digits in this case), helping to ensure	the
       lexical sort puts them in the correct order.

   nsort_by
	  @vals	= nsort_by { KEYFUNC } @vals

       Similar to "sort_by" but	compares its key values	numerically.

   rev_sort_by
   rev_nsort_by
	  @vals	= rev_sort_by {	KEYFUNC	} @vals

	  @vals	= rev_nsort_by { KEYFUNC } @vals

       Since version 0.06.

       Similar to "sort_by" and	"nsort_by" but returns the list	in the reverse
       order. Equivalent to

	  @vals	= reverse sort_by { KEYFUNC } @vals

       except that these functions are slightly	more efficient because they
       avoid the final "reverse" operation.

   max_by
	  $optimal = max_by { KEYFUNC }	@vals

	  @optimal = max_by { KEYFUNC }	@vals

       Returns the (first) value from @vals that gives the numerically largest
       result from the key function.

	  my $tallest =	max_by { $_->height } @people

	  use File::stat qw( stat );
	  my $newest = max_by {	stat($_)->mtime	} @files;

       In scalar context, the first maximal value is returned. In list
       context,	a list of all the maximal values is returned. This may be used
       to obtain positions other than the first, if order is significant.

       If called on an empty list, an empty list is returned.

       For symmetry with the "nsort_by"	function, this is also provided	under
       the name	"nmax_by" since	it behaves numerically.

   min_by
	  $optimal = min_by { KEYFUNC }	@vals

	  @optimal = min_by { KEYFUNC }	@vals

       Similar to "max_by" but returns values which give the numerically
       smallest	result from the	key function. Also provided as "nmin_by"

   minmax_by
	  ( $minimal, $maximal ) = minmax_by { KEYFUNC } @vals

       Since version 0.11.

       Similar to calling both "min_by"	and "max_by" with the same key
       function	on the same list. This version is more efficient than calling
       the two other functions individually, as	it has less work to perform
       overall.	In the case of ties, only the first optimal element found in
       each case is returned. Also provided as "nminmax_by".

   uniq_by
	  @vals	= uniq_by { KEYFUNC } @vals

       Returns a list of the subset of values for which	the key	function block
       returns unique values. The first	value yielding a particular key	is
       chosen, subsequent values are rejected.

	  my @some_fruit = uniq_by { $_->colour	} @fruit;

       To select instead the last value	per key, reverse the input list. If
       the order of the	results	is significant,	don't forget to	reverse	the
       result as well:

	  my @some_fruit = reverse uniq_by { $_->colour	} reverse @fruit;

       Because the values returned by the key function are used	as hash	keys,
       they ought to either be strings,	or at least well-behaved as strings
       (such as	numbers, or object references which overload stringification
       in a suitable manner).

   partition_by
	  %parts = partition_by	{ KEYFUNC } @vals

       Returns a key/value list	of ARRAY refs containing all the original
       values distributed according to the result of the key function block.
       Each value will be an ARRAY ref containing all the values which
       returned	the string from	the key	function, in their original order.

	  my %balls_by_colour =	partition_by { $_->colour } @balls;

       Because the values returned by the key function are used	as hash	keys,
       they ought to either be strings,	or at least well-behaved as strings
       (such as	numbers, or object references which overload stringification
       in a suitable manner).

   count_by
	  %counts = count_by { KEYFUNC } @vals

       Since version 0.07.

       Returns a key/value list	of integers, giving the	number of times	the
       key function block returned the key, for	each value in the list.

	  my %count_of_balls = count_by	{ $_->colour } @balls;

       Because the values returned by the key function are used	as hash	keys,
       they ought to either be strings,	or at least well-behaved as strings
       (such as	numbers, or object references which overload stringification
       in a suitable manner).

   zip_by
	  @vals	= zip_by { ITEMFUNC } \@arr0, \@arr1, \@arr2,...

       Returns a list of each of the values returned by	the function block,
       when invoked with values	from across each each of the given ARRAY
       references. Each	value in the returned list will	be the result of the
       function	having been invoked with arguments at that position, from
       across each of the arrays given.

	  my @transposition = zip_by { [ @_ ] }	@matrix;

	  my @names = zip_by { "$_[1], $_[0]" }	\@firstnames, \@surnames;

	  print	zip_by { "$_[0]	=> $_[1]\n" } [	keys %hash ], [	values %hash ];

       If some of the arrays are shorter than others, the function will	behave
       as if they had "undef" in the trailing positions. The following two
       lines are equivalent:

	  zip_by { f(@_) } [ 1,	2, 3 ],	[ "a", "b" ]
	  f( 1,	"a" ), f( 2, "b" ), f( 3, undef	)

       The item	function is called by "map", so	if it returns a	list, the
       entire list is included in the result. This can be useful for example,
       for generating a	hash from two separate lists of	keys and values

	  my %nums = zip_by { @_ } [qw(	one two	three )], [ 1, 2, 3 ];
	  # %nums = ( one => 1,	two => 2, three	=> 3 )

       (A function having this behaviour is sometimes called "zipWith",	e.g.
       in Haskell, but that name would not fit the naming scheme used by this
       module).

   unzip_by
	  $arr0, $arr1,	$arr2, ... = unzip_by {	ITEMFUNC } @vals

       Since version 0.09.

       Returns a list of ARRAY references containing the values	returned by
       the function block, when	invoked	for each of the	values given in	the
       input list.  Each of the	returned ARRAY references will contain the
       values returned at that corresponding position by the function block.
       That is,	the first returned ARRAY reference will	contain	all the	values
       returned	in the first position by the function block, the second	will
       contain all the values from the second position,	and so on.

	  my ( $firstnames, $lastnames ) = unzip_by { m/^(.*?) (.*)$/ }	@names;

       If the function returns lists of	differing lengths, the result will be
       padded with "undef" in the missing elements.

       This function is	an inverse of "zip_by",	if given a corresponding
       inverse function.

   extract_by
	  @vals	= extract_by { SELECTFUNC } @arr

       Since version 0.05.

       Removes elements	from the referenced array on which the selection
       function	returns	true, and returns a list containing those elements.
       This function is	similar	to "grep", except that it modifies the
       referenced array	to remove the selected values from it, leaving only
       the unselected ones.

	  my @red_balls	= extract_by { $_->color eq "red" } @balls;

	  # Now	there are no red balls in the @balls array

       This function modifies a	real array, unlike most	of the other functions
       in this module. Because of this,	it requires a real array, not just a
       list.

       This function is	implemented by invoking	"splice" on the	array, not by
       constructing a new list and assigning it. One result of this is that
       weak references will not	be disturbed.

	  extract_by { !defined	$_ } @refs;

       will leave weak references weakened in the @refs	array, whereas

	  @refs	= grep { defined $_ } @refs;

       will strengthen them all	again.

   extract_first_by
	  $val = extract_first_by { SELECTFUNC } @arr

       Since version 0.10.

       A hybrid	between	"extract_by" and "List::Util::first". Removes the
       first element from the referenced array on which	the selection function
       returns true, returning it.

       As with "extract_by", this function requires a real array and not just
       a list, and is also implemented using "splice" so that weak references
       are not disturbed.

       If this function	fails to find a	matching element, it will return an
       empty list in list context. This	allows a caller	to distinguish the
       case between no matching	element, and the first matching	element	being
       "undef".

   weighted_shuffle_by
	  @vals	= weighted_shuffle_by {	WEIGHTFUNC } @vals

       Since version 0.07.

       Returns the list	of values shuffled into	a random order.	The
       randomisation is	not uniform, but weighted by the value returned	by the
       "WEIGHTFUNC". The probabilty of each item being returned	first will be
       distributed with	the distribution of the	weights, and so	on recursively
       for the remaining items.

   bundle_by
	  @vals	= bundle_by { BLOCKFUNC	} $number, @vals

       Since version 0.07.

       Similar to a regular "map" functional, returns a	list of	the values
       returned	by "BLOCKFUNC".	Values from the	input list are given to	the
       block function in bundles of $number.

       If given	a list of values whose length does not evenly divide by
       $number,	the final call will be passed fewer elements than the others.

TODO
       o   XS implementations

	   These functions are currently all written in	pure perl. Some	at
	   least, may benefit from having XS implementations to	speed up their
	   logic.

       o   Merge into List::Util or List::MoreUtils

	   This	module shouldn't really	exist. The functions should instead be
	   part	of one of the existing modules that already contain many list
	   utility functions.  Having Yet Another List Utilty Module just
	   worsens the problem.

	   I have attempted to contact the authors of both of the above
	   modules, to no avail; therefore I decided it	best to	write and
	   release this	code here anyway so that it is at least	on CPAN. Once
	   there, we can then see how best to merge it into an existing
	   module.

	   Updated 2015/07/16: As I am now the maintainer of List::Util, some
	   amount of merging/copying should be possible. However, given	the
	   latter's key	position in the	core perl distribution and head	of the
	   "CPAN River"	I am keen not to do this wholesale, but	a selected
	   pick	of what	seems best, by a popular consensus.

       o   "head" and "tail"-like functions

	   Consider perhaps

	      head_before { COND } LIST	 # excludes terminating	element
	      head_upto	  { COND } LIST	 # includes terminating	element

	      tail_since  { COND } LIST	 # includes initiating element
	      tail_after  { COND } LIST	 # excludes initiating element

	   (See	also <https://rt.cpan.org/Ticket/Display.html?id=105907>).

AUTHOR
       Paul Evans <leonerd@leonerd.org.uk>

perl v5.32.1			  2018-01-31		      List::UtilsBy(3)

NAME | SYNOPSIS | DESCRIPTION | FUNCTIONS | TODO | AUTHOR

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=List::UtilsBy&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help