my @results = grep $expression, @input_list;
my $count = grep $expression, @input_list;
Here, $expression is a scalar expression that
should refer to $_ (explicitly or implicitly). For
example, find all the numbers greater than 10:
my @input_numbers = (1, 2, 4, 8, 16, 32, 64);
my @bigger_than_10 = grep $_ > 10, @input_numbers;
The result is just 16, 32, and 64. This uses an explicit reference to
$_. Here's an example of an
implicit reference to $_ that's
similar to pattern matching:
my @end_in_4 = grep /4$/, @input_numbers;
And now you find just 4 and 64.
If the testing expression is complex, you can hide it in a subroutine:
my @odd_digit_sum = grep digit_sum_is_odd($_), @input_numbers;
sub digit_sum_is_odd {
my $input = shift;
my @digits = split //, $input; # Assume no nondigit characters
my $sum;
$sum += $_ for @digits;
return $sum % 2;
}
Now you get back the list of 1, 16, and 32. These numbers have a
digit sum with a remainder of "1"
in the last line of the subroutine, which counts as true.
my @results = grep { block; of; code; } @input_list;
my $count = grep { block; of; code; } @input_list;
Just like the expression form, each element of the input list is
placed temporarily into $_. Next, the entire block
of code is evaluated. The last expression evaluated in the block
(evaluated in a scalar context) is used like the testing expression
in the expression form. Because it's a full block,
you can introduce variables that are local to the block.
Let's rewrite that last example to use the block
form:
my @odd_digit_sum = grep {
my $input = $_;
my @digits = split //, $input; # Assume no nondigit characters
my $sum;
$sum += $_ for @digits;
$sum % 2;
} @input_numbers;