Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Grep Fuunction

by iceraider (Initiate)
on Jun 11, 2002 at 12:12 UTC ( #173538=perlquestion: print w/replies, xml ) Need Help??

iceraider has asked for the wisdom of the Perl Monks concerning the following question:

I looked up the grep function and I don't really understand, what is it good, for and same for map.

Replies are listed 'Best First'.
Re: Grep Fuunction
by Abigail-II (Bishop) on Jun 11, 2002 at 12:24 UTC
    They are both filters working on a list. For each element of the list, the first argument of grep or map is executed (this argument being either an expression or a block). Just before the execution, $_ is set the element being processed.

    grep and map differ in the return values. The former will always returns a subset of the original list (the entire list is a subset as well). An element of the original list will be returned if the expression (or block) returned a true value when that element was processed. The return value of map is a list consisting of the actual return values of the expression or block.


      I swear on life, I have read every perldoc and Monastery Example on map (and sometimes grep). Pages and pages of intructions, and just have since avoided using it.
      But now I get it!
      One little paragraph, thank you so much! Maybe you should re-write all the perldocs ;-)

Re: Grep Function
by tadman (Prior) on Jun 11, 2002 at 12:28 UTC
    As Abigail-II has explained the functionality, here's an example of how they can come in handy. Before:
    my @foo_bar; foreach my $foo (@fooz) { if ($foo > 12) { push(@foo_bar, $foo - 1); } }
    Instead you could use a combination of map and grep:
    my @foo_bar = map { $_ - 1 } grep { $_ > 12 } @fooz;
    These constructs can be chained together and that is what makes them highly adaptable. Data flows right to left, though, so watch out.
Re: Grep Function
by joealba (Hermit) on Jun 11, 2002 at 12:56 UTC
    Take the time to learn the ways of grep and map. They are very powerful tools in the Swiss Army Knife of Perl.

    Do a few Perlmonks Google searches, check out some of the Monks' code snippets, and you will find some great examples of how grep and map are your friends.

    Like these:
    Map Tutorial: The Basics
    Map and Grep
Re: Grep Fuunction
by swiftone (Curate) on Jun 11, 2002 at 13:06 UTC
    I'm assuming you can decipher how they work from the docs, and you're trying to figure out why you would use them.

    There are many, many uses. Here are a few examples:

    From the perldoc on readdir():

    opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!"; @dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR); closedir DIR;
    Here grep was used to take the array from readdir() and filter out non-start-with-dot-files

    Here's one I use often: I might have an array of values, that, at some point, I need to do a series of checks to see if a value is in the array. It's inefficient to loop through the array multiple times. Likewise, we mostly need this data as an array, not a hash, this is just the exception. So we use map() to copy it to a hash:

    my @array = qw(One Two Five Nine); my %check_hash = map {$_ => 1} @array;
    Now we can check for the existence of $foo in @array by checking $check_hash{$foo} for truth (or existence)

    Let's say you're doing a database update, but you have a variable number of fields. In fact, you have the fields as @fields. Let's also assume you have a CGI object in $q that has all the needed fields there (and taint-checked)

    @fields = qw(Name ID Age); #assuming $dbh and $q exist, and primary key in $key my $statement = 'update my_table '.join(",", map {"set $_ = ?"} @fie +lds)." where Key=?"; my $sth = $dbh->prepare($statement); $sth->execute(map({$q->param($_)} @fields), $key);
    Unrolling this, we take each value in @field, and make it instead the text "set (value) =?". We then join those elements to end up with a legit SQL statement. In the execute() call, we want the $q->param() value foreach element of we use map() to get it.

    What if we didn't have $key defined in the above? I mean, what if $key was the name of the field that was the primary key, and the value was taken from the passed parameters? A slight modification that would use grep():

    @fields = qw(Name ID Age Key); #assuming $dbh and $q exist, and primary key name in $key #we don't want to change the value of the key! my $statement = 'update my_table '.join(",", map {"set $_ = ?"} grep +(!/^$key$/, @fields))." where $key=?"; my $sth = $dbh->prepare($statement); $sth->execute(map({$q->param($_)} @fields));
    Now the Key field is only used where needed. (Note this code woudl break if key wasn't last. It would be more durable if the execute() call also grepped out the key, then explicitly added it to the end:
    $sth->execute(map({$q->param($_} grep(!/^$key$/, @fields)), $q->param( +$key));
    (And one last caveat -- $key will be interpretted as a regex. For alphanumeric keys, that's not a problem.)

    Hope that helps, there are many more examples out there. In general, use grep when you need part of an array as an array, and use map when you need an array based off another list. If you need to actually execute code based on the contents of a list, you're better off using a loop.

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://173538]
Approved by Zaxo
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2023-12-02 17:41 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (18 votes). Check out past polls.