Reputation: 25
map, according to the definition, takes a list on which we can perform some transformations and then return it as a list. Some may even go and call it as a for loop in disguise.
I recently came across some code which in simple terms was using for and map together. For example:
perl -wE'@a=(1..5); say $_ for map { $_+=10 } @a'
11
12
13
14
15
My question is, is there an easy to way to remember when to use for and map together. Can someone please explain why is that for needed?
Upvotes: 0
Views: 130
Reputation: 74685
Perhaps it would be helpful to split up the steps. The following code is functionally equivalent to your one-liner:
use strict;
use warnings;
use feature 'say';
my @a = 1 .. 5;
# @mapped contains the result of applying the block to each element of @a
my @mapped = map { $_ += 10 } @a;
say for @mapped;
Note that it is unnecessary (and perhaps undesirable) to use $_ += 10
in your script, as this is modifying the elements in the original array @a
. Using $_ + 10
instead means that the returned value is different but the original value remains unmodified.
You don't need to use map
as well as for
, it just splits the process into two steps. Your code could just as easily be:
my @a = 1 .. 5;
say $_ + 10 for @a;
or
my @a = 1 .. 5;
map { say $_ + 10 } @a;
Upvotes: 1
Reputation: 77155
Let's check what it means using B::Deparse
$ perl -MO=Deparse -wE'@a=(1..5); say $_ for map { $_+=10 } @a'
BEGIN { $^W = 1; }
use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
@a = 1..5;
say $_ foreach (map {$_ += 10;} @a);
-e syntax OK
So basically, you
-w
. -E
. @a
with 5 elements. @a
and using map to transform the array content while modifying the array as well. So bottom line as others have mentioned, for
is just needed to iterate over the list that is returned by map
.
Upvotes: 1
Reputation: 13792
You can simplify your example:
perl -wE 'map { say $_+=10 } (1..5)'
As you see, map can be used to execute code of each item. I use map when I have to transform an array into another one. Your example is (IMO) more readable with a for loop:
perl -wE 'say $_+=10 for(1..5)'
Upvotes: 1
Reputation: 265707
map
returns a new list, for
iterates over that list. Your for map
line basically boils down to:
@a=(1..5);
@mapped = map { $_+=10 } @a;
for (@mapped) {
say $_;
}
Upvotes: 1
Reputation: 27812
The for
is used to loop through the list returned by map
and print out each element.
Your example has the same effect as:
@l = map {$_ += 10} @a;
for (@l) {
say $_;
}
If all you want is the list, then you don't need for
:
@l = map {$_ += 10} @a
Upvotes: 3