4.14. Finding All Elements in an Array Matching Certain Criteria
4.14.1. Problem
From
a list, you want only the elements that match certain
criteria. This notion of extracting a subset of a larger list is common. It''s
how you find all engineers in a list of employees, all users in the
"staff" group, or all the filenames you''re interested in.
4.14.2. Solution
Use grep to apply
a condition to all elements in the list and return only those for
which the condition was true:
@MATCHING = grep { TEST ($_) } @LIST;
4.14.3. Discussion
This could also be accomplished with a foreach
loop:
@matching = ( );
foreach (@list) {
push(@matching, $_) if TEST ($_);
}
The Perl grep function is shorthand for all that
looping and mucking about. It''s not really like the Unix
grep command; it doesn''t have options to return
line numbers or to negate the test, and it isn''t limited to
regular-expression tests. For example, to filter out just the large
numbers from an array or to find out which keys in a hash have very
large values:
@bigs = grep { $_ > 1_000_000 } @nums;
@pigs = grep { $users{$_} > 1e7 } keys %users;
Here''s something that sets @matching to lines from
the who command that start with
"gnat ":
@matching = grep { /^gnat / } `who`;
Here''s another example:
@engineers = grep { $_->position( ) eq "Engineer" } @employees;
It extracts only those objects from the array
@employees whose position
method returns the string Engineer.You could have even more complex tests in a grep:
@secondary_assistance = grep { $_->income >= 26_000 &&
$_->income < 30_000 }
@applicants;
But at that point you may decide it would be more legible to write a
proper loop instead.
4.14.4. See Also
The "For Loops," "Foreach Loops," and "Loop Control" sections of
perlsyn(1) and Chapter 4 of
Programming Perl; the grep
function in perlfunc(1) and Chapter 29 of
Programming Perl; your system''s
who(1) manpage, if it exists; Recipe 4.13