anujpaliwal
anujpaliwal

Reputation: 25

Use of for with map

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

Answers (5)

Tom Fenech
Tom Fenech

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

jaypal singh
jaypal singh

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

  • Enabled the warnings using -w.
  • Enabled new features using -E.
  • Create an array @a with 5 elements.
  • Finally, iterating through the array @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

Miguel Prz
Miguel Prz

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

knittl
knittl

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

jh314
jh314

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

Related Questions