Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: playing with map

by archon (Monk)
on Mar 09, 2001 at 13:15 UTC ( [id://63203]=note: print w/replies, xml ) Need Help??


in reply to playing with map

map and grep are two different functions for a reason.

map basically says "take this list, do something to every element in it, and give me the resulting list."

grep basically says "take this list, find all elements for which this expression is true, and give me the resulting list."

in general you don't want to use either of these functions in a void context, i.e. you wouldn't run them without assigning the list they return to some variable. also, you wouldn't want to use them unless you want to iterate through the entire list. in either of these situations, a foreach loop (with a call to last in the second situation) is more appropriate.

your realization and reconstruction of the map usage to assign the results of the operation to @n was correct. you couldn't do it with a grep call, because grep returns some subset of the original list. it doesn't make any modifications. also, as you said, why would you want to?

Update:Whoops.. guess i should have re-read the grep info before i made that last statement (=

Replies are listed 'Best First'.
Re: Re: playing with map
by snowcrash (Friar) on Mar 09, 2001 at 13:45 UTC
    > you couldn't do it with a grep call, because grep returns
    > some subset of the original list. it doesn't make any
    > modifications.

    wrong. you could use grep, and it is destructive to the input list. something like this works:
    my @n = grep s/$_/$count+=$_;$_=$count/e, <DATA>;
    i know it doesn't make any sense to use grep here, but it can be done.

    cheers snowcrash //////
Re: Re: playing with map
by jeroenes (Priest) on Mar 09, 2001 at 13:51 UTC
    Ahum, grep can be used to modify the list. From perlfunc (at my system, 5.6):

    Note that, because `$_' is a reference into the list value, it can be used to modify the elements of the array. While this is useful and supported, it can cause bizarre results if the LIST is not ...

    Jeroen
    "We are not alone"(FZ)

      Well, kinda. With grep, for each item you can only:

      • Leave the item alone and not include it in the result
      • Modify the original item and not include it in the result
      • Include the original item, unmodified, in the result
      • Modify the original item and include this exact same modification in the result
      With map you can do all of the above and also do:
      • Leave the item alone and include one or more values in place of that item in the result
      • Modify the item and include one or more values in place of that item in the result, with the ability to even include the original (unmodified) item in the result.
      So using grep to return something other than a subset of the original list is quite restricted and is probably an indication that you shouldn't be using grep. (:

              - tye (but my friends call me "Tye")
        So using grep to return something other than a subset of the original list is quite restricted and is probably an indication that you shouldn't be using grep. (:

        I have been guilty of writing

        do_something() if (grep /something/, @array);
        is this a "wrongly" used grep? Should I be writing something like-
        foreach (@array){ &do_something() and last if /something/; }
        ... the grep seems easier on the eye IMO. Is it OK if you know the data source is always going to be small?
      What tye said. Just because you can do something doesn't mean that it isn't also a really stupid idea to do it. Using map or grep in void context is a sign of someone who has picked up bad habits.

      UPDATE
      I was asked why talking about modifying the input list triggered comments about void context from me and tye. Here is why. The typical bad idiom you see is to use a grep in void context to change the input list. Hence the alarm. Note that it is usually a bad idea to modify the input list when not in void context, but occasionally it may be natural to do that. For instance the input list is temporary, and you want to both filter and modify in an obvious way. Here is an example of a case where it would fit:

      return grep s/^FOR_PRINT://, <FILE>;
      In my experience these cases tend to be rare.

      UPDATE 2
      merlyn is right. I would have to work harder to come up with a place where modifying the input list makes sense. Given that I am not feeling well, I don't feel like doing that, and given that I think it is a bad idea, I don't think I should bother...

        return grep s/^FOR_PRINT://, <FILE>;
        But even that can be trivially written as:
        return map /^FOR_PRINT(.*)/s, <FILE>;
        And thus not lose 5 style points for altering $_, which in my all-too-often experience spits out an "attempt to modify read-only value" when I least expect it.

        -- Randal L. Schwartz, Perl hacker

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://63203]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-03-29 06:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found