Map and Grep

map

map {BLOCK} LIST
For example:
my @chars = qw(a b c d e);
my @uppercased_chars = map { uc($_) } @chars;

map is a function that operates on a list and returns a list. map executes the block of code in curly braces for each element of the list on the right, and emits the new list. It sets $_ to each element in the list and then sends that element through the curly braces. In the example above, each element of @chars gets sent individually to the uc() function, then all the uc()'ed characters get assigned into the new @uppercased_chars array.

Note that map is very similar to a foreach loop. You can use a foreach loop instead, but often map makes for more compact and efficient code (note that compact isn't always better--you should make sure your code isn't overly cryptic!).

Here's an example that takes a list and squares each element:

my @squares = map { $_ ** 2 } qw(1 2 3 4 5 6 7 8 9);

grep

grep {BLOCK} LIST
For example:
my @nums = qw(10 -7 35 15 -1 0 1 99);
my @big_nums = grep { $_ > 20 } @nums;

grep is a function that allows you to select elements from a list based on a boolean pattern match or expression. It uses a localized $_ inside of the enclosing block for each element of the list.

In the example above, @big_nums will hold all the numbers from @nums that are bigger than 20.

You can actually use grep in list or scalar context. In list context, grep returns a list of elements for which the expression is true. In scalar context, it returns the number of times the expression was true.

grep is often used with regular expressions to make an efficient filter.

my @no_blank_lines = grep { $_ !~ /^\s*$/ } <FILE>
my @comments       = grep { /^\s*#/ } <FILE>
Here's another example of grep, this time to find which visitors are allowed, according to a hash of approved visitors:
my @visitors = qw(Sarah Joel Susan Wanda Fred);

my %allowed  = ( Wanda => 1,
                 Susan => 1,
                 Fred  => 1 );

my @allowed_visitors = grep { $allowed{$_} } @visitors;
# how many elements in @allowed_visitors now? 

Examples:

Create a hash out of an array so that later on we can tell if an element is present in the array:

my @names = qw(Sarah Joel Susan Wanda Fred);
my %names = map { $_ => 1 } @names;

# later on in the code...

print "Name? ";
chomp (my $name = <STDIN>);

if ($names{$name}) {
    print "Yes, $name is present.\n";
} else {
    print "No, $name isn't here.\n";
}
Here's a more advanced example that makes use of both grep and map to square only even numbers.
@numbers = qw(1 12 7 99 102 4 5 32 11);

@squared_evens = map { $_ ** 2 }
                 grep { $_ % 2 == 0 }
                 @numbers;


UW Extension Perl Programming
Course Three, Perl, the Web, and Databases
March 26 - June 04, 2007 (note no class May 28)
Monday evenings
10 Sessions, 6:00 to 9:00 PM

Instructor:
Joel Grow (joelg at u.washington.edu)
links:
perl.com
cpan
perldoc online
learn.perl.org
perlmonks.org
seattle perl users group (spug)
perl.com
 
Thursday, May 24, 2012
you're number: 847