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

Hi all,
Could you please give me some idea when we can use "map" and grep?
from google search I got the following expln:

grep-> extracts any element from an array for which expression is true.

map-> evaluate block or expression for each element of an array.

So can anyone please give me an idea on which case map and grep can be applied?

Thanks

Replies are listed 'Best First'.
Re: map and grep
by smahesh (Pilgrim) on Feb 20, 2007 at 08:17 UTC

    In simple terms, use map for transformation and grep for filtering.

    See the following code snippet

    my @ints = qw(1 2 3 4 5); my @doubleints = map { $_ * 2 } @ints; my @odds = grep { $_ % 2 } @ints; print "INTS = " . join(",", @ints) . "\n"; print "DOUBLE = " . join(",", @doubleints) . "\n"; print "ODDS = " . join(",", @odds) . "\n"; ----------- OUTPUT ------ INTS = 1,2,3,4,5 DOUBLE = 2,4,6,8,10 ODDS = 1,3,5
    Update: Thanks to bart for pointing out that I had not closed the italics - used <i> instead of </i> for closing tag.

    Mahesh

Re: map and grep
by Moron (Curate) on Feb 20, 2007 at 12:25 UTC
    grep expression,-or-block list

    returns a new list containing those elements of list for which expression or block produces a true value, whereas

    map expression,-or-block list

    performs the expression or block for each element of list and returns the list of values the expression produced (i.e. one (*!) for each element supplied in the "input" list).

    Both of these update the default variable $_ with the current list element before executing the expression or block. Examples:

    my @sources = grep /\.c$/, glob '*'; # get only the files ending in .c + from a listing of the working directory my @objects = map s/\.c$/\.o/, @sources; # get the list of object file +s that a c compiler would make by default from the files now in @sour +ces my @virgins = map { my $c = $_; $c =~ s/\.o$/\.c/; system "cc $c"; $c } grep !(-f), @objects; # find and compile the uncompiled sources
    (*! Update: unless of course the expression generates more than one or zero values per iteration as johngg points out below)

    -M

    Free your mind

      (i.e. one for each element supplied in the "input" list)

      That's usually what happens but you can produce more than one "output" for each "input", like this for example

      $ perl -le ' -> @list = map { ($_ - 1, $_, $_ + 1) } 3, 6, 9; -> print qq{@list};' 2 3 4 5 6 7 8 9 10 $

      Cheers,

      JohnGG

Re: map and grep
by chakram88 (Pilgrim) on Feb 20, 2007 at 12:10 UTC
    smahesh Re: map and grep gave a very good synopsis of the difference.

    Another key difference is right there in your OP (this expands on smahesh's remark)

    • grep --- use it when you want to extract certain elements of a list based on certain criteria
    • map --- use this when you want to do something to every element of a list

    Note with both the difference in the return value depending on the context in which it's called.

    perldoc -f grep

    perldoc -f map

Re: map and grep
by planetscape (Chancellor) on Feb 21, 2007 at 04:11 UTC
Re: map and grep
by ikegami (Patriarch) on Feb 20, 2007 at 16:06 UTC
    Don't forget apply. I have previously posted a good answer to your question.

    You want grep to remove rows, while map and List::MoreUtils's apply transforms rows.

    When using grep or map, don't change $_ unless you want to change the original array.

    apply is similar to map, but you can safely modify $_. The downside to using apply is that you're limited to 1:1 transformations (whereas map is extremely flexible).

    use List::MoreUtils qw( apply ); my @orig = qw( Just another Perl hacker ); my @grepped = grep { /^[A-Z]/ } @orig; my @mapped = map { uc } @orig; my @applied = apply { s/[aiueo]//ig } @orig; print("@orig\n"); # Just another Perl hacker print("@grepped\n"); # Just Perl print("@mapped\n"); # JUST ANOTHER PERL HACKER print("@applied\n"); # Jst nthr Prl hckr

    List::MoreUtils can easily be installed if you're using ActivePerl. Just type by ppm install List-MoreUtils at the prompt

Re: map and grep
by Anonymous Monk on Feb 20, 2007 at 08:11 UTC