Algorithm-Loops
view release on metacpan or search on metacpan
lib/Algorithm/Loops.pm view on Meta::CPAN
=back
=head3 Usage
The MapCar* functions are all like C<map> except they each loop over more
than one list at the same time.
[ The name "mapcar" comes from LISP. As I understand it, 'car' comes from
the acronym for a register of the processor where LISP was first
developed, one of two registers used to implement lists in LISP. I only
mention this so you won't waste too much time trying to figure out what
"mapcar" is supposed to mean. ]
The MapCar* functions all have prototype specifications of (\&@).
This means that they demand that the first argument that you pass be a
CODE reference. After that you should pass zero or more array references.
Your subroutine is called (in a list context) and is passed the first
element of each of the arrays whose references you passed in (in the
corresponding order). Any value(s) returned by your subroutine are
pushed onto an array that will eventually be returned by MapCar*.
Next your subroutine is called and is passed the B<second> element of
each of the arrays and any value(s) returned are pushed onto the results
array. Then the process is repeated with the B<third> elements.
This continues until your subroutine has been passed all elements [except
for some cases with MapCarMin()]. If the longest array whose reference
you passed to MapCar() or MapCarU() contained $N elements, then your
subroutine would get called $N times.
Finally, the MapCar* function returns the accumulated list of values. If
called in a scalar context, the MapCar* function returns a reference to
an array containing these values.
[ I feel that having C<map> return a count when called in a scalar
context is quite simply a mistake that was made when this feature was
copied from C<grep> without properly considering the consequences.
Although it does make for the impressive and very impractical golf
solution of:
$sum=map{(1)x$_}@ints;
for adding up a list of natural numbers. q-: ]
=head3 Differences
The different MapCar* functions are only different in how they deal with
being pqssed arrays that are not all of the same size.
If not all of your arrays are the same length, then MapCarU() will pass
in C<undef> for any values corresponding to arrays that didn't have
enough values. The "U" in "MapCarU" stands for "undef".
In contrast, MapCar() will simply leave out values for short arrays (just
like I left the "U" out of its name).
MapCarE() will croak without ever calling your subroutine unless all of
the arrays are the same length. It considers it an Error if your arrays
are not of Equal length and so throws an Exception.
Finally, MapCarMin() only calls your subroutine as many times as there
are elements in the B<shortest> array.
In other words,
MapCarU \&MySub, [1,undef,3], [4,5], [6,7,8]
returns
( MySub( 1, 4, 6 ),
MySub( undef, 5, 7 ),
MySub( 3, undef, 8 ),
)
While
MapCar \&MySub, [1,undef,3], [4,5], [6,7,8]
returns
( MySub( 1, 4, 6 ),
MySub( undef, 5, 7 ),
MySub( 3, 8 ),
)
While
MapCarMin \&MySub, [1,undef,3], [4,5], [6,7,8]
returns
( MySub( 1, 4, 6 ),
MySub( undef, 5, 7 ),
)
And
MapCarE \&MySub, [1,undef,3], [4,5], [6,7,8]
dies with
MapCarE: Arrays with different sizes (3 and 2)
=head3 Examples
Transposing a two-dimensional matrix:
my @transposed= MapCarE {[@_]} @matrix;
or, using references to the matrices and allowing for different row
lengths:
my $transposed= MapCarU {[@_]} @$matrix;
Formatting a date-time:
my $dateTime= join '', MapCarE {
sprintf "%02d%s", pop()+pop(), pop()
} [ (localtime)[5,4,3,2,1,0] ],
( run in 1.692 second using v1.01-cache-2.11-cpan-97f6503c9c8 )