Section 16.3. Transforming Items from a List with map


16.3. Transforming Items from a List with map

Another common task is transforming items from a list. For example, suppose you have a list of numbers to format as money numbers for output, as with the subroutine &big_money (from Chapter 13). We don't want to modify the original data, and we need a modified copy of the list just for output. Here's one way to do that:

     my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);     my @formatted_data;     foreach (@data) {       push @formatted_data, &big_money($_);     } 

That looks similar in form to the example code used at the beginning of the section on grep, doesn't it? The replacement code resembles the first grep example:

     my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);     my @formatted_data = map { &big_money($_) } @data; 

The map operator looks much like grep because it has the same kind of arguments: a block that uses $_ and a list of items to process. It operates in a similar way, evaluating the block once for each item in the list with $_ aliased to a different original list element each time. But the last expression of the block is used differently; instead of giving a Boolean value, the final value becomes part of the resulting list.[*] Any grep or map statement could be rewritten as a foreach loop pushing items onto a temporary array. But the shorter way is typically more efficient and convenient. Since the result of map or grep is a list, it can be passed directly to another function. Here we can print that list of formatted money numbers as an indented list under a heading:

[*] One other important difference is the expression used by map is evaluated in a list context and may return any number of items, not necessarily one each time.

     print "The money numbers are:\n",       map { sprintf("%25s\n", $_) } @formatted_data; 

We could have done that processing all at once without the temporary array @formatted_data:

     my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);     print "The money numbers are:\n",       map { sprintf("%25s\n", &big_money($_) ) } @data; 

As we saw with grep, there's a simpler syntax for map. If all you need for the selector is a simple expression (rather than a whole block), you can use that expression, followed by a comma, in place of the block:

     print "Some powers of two are:\n",       map "\t" . ( 2 ** $_ ) . "\n", 0..15; 



Learning Perl
Learning Perl, 5th Edition
ISBN: 0596520107
EAN: 2147483647
Year: 2003
Pages: 232

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net