Loops #4

#0 | #1 | #2 | #3 | #4

map

While not a formal loop construct, map (technically a function) is used in a similar manner. It works like this in general:

map BLOCK LIST

map EXPRESSION, LIST

For each item of LIST, it evaluates the BLOCK or EXPRESSION, and returns the list of results of each evaluation.

map evaluates in a list context, so each element of LIST may produce one or more elements - including zero (0) elements.

An example should help clear that up:

my @foo = ("alpha","bravo","charlie","delta","echo","foxtrot","golf","hotel", 
"india","juliet","kilo","lima","mike","november","oscar","papa","quebec",
"romeo","sierra","tango","uniform","victor","whiskey","xray","yankee","zulu");

print join "\n",(reverse sort map {uc} @foo);

Woops. That's for the advanced class. It shows a bit of the power of list operators when stacked up.

If you're interested here's what it does in English: (read from right to left)

  1. take each item of array @foo
  2. pass it to map which puts each item in uppercase
  3. then passes the items to sort which sorts them
  4. the sorted list is then reversed (sorted in the opposite order)
  5. finally passes to the print function, which 'joins' each item with a newline

Wow - you gotta love Perl.

Getting back to our level ...

@foo = (1 .. 10);
map {$_ *= 2} (@foo);
print join(", ",@foo);
print "\nfirst element: $foo[0]\n";

Note how similar this is to a foreach loop:

@foo = (1 .. 10);
foreach (@foo) { $_ *= 2; }
print join(", ",@foo);
print "\nfirst element: $foo[0]\n";

There is a little problem with both these code examples: $_ (our loop index) is altered when going through the loop.

Therefore it would be better to leave it intact by assigning a local variable to it:

@foo = (1 .. 10);
print join(", ",(map {my $i = $_; $i *= 2} (@foo)));
print "\nfirst element: $foo[0]\n";

Another 'loop' structure is grep, found here.

Next we delve into sorting ...