Friday 25 September 2009

difference between foreach and map

map creates a new list from an existing list by applying a function to each existing member.

Use foreach if you want to trigger actions based on list members, not just create new list members.

For example – working from a list of contacts you might want to send a message to everyone whose name matches some string. You’ve no reason to create a new list in this case.

To message an agent – or not – assume we have this function:

   1: -module(play).
   2: -export([message/1]).
   3:  
   4: message({Agent,Location}) when Agent == "John" ->
   5:     io:format("Messaging ~w in ~w~n",[Agent,Location]);
   6: message({Agent,Location}) ->
   7:     io:format("No message for ~w~n",[Agent]).
5> play:message({"John","Buenos Aires"}).
Messaging [74,111,104,110] in [66,117,101,110,111,115,32,65,105,114,101,115]
ok
6> play:message({"Jeff","Buenos Aires"}).
No message for [74,101,102,102]
ok

(Ha, unexpectedly turns strings to lists of ASCII character codes. Need to look into string handling.)

3> lists:foreach(fun play:message/1, [{"John","Buenos Aires"}, {"Jules","Nairobi"}]).
Messaging [74,111,104,110] in [66,117,101,110,111,115,32,65,105,114,101,115]
No message for [74,117,108,101,115]
ok

Surprised by the need to recast our message function explicitly as a fun to pass it to foreach. Need to look into that too. Is it because passing a naked play:message/1 looks like an atom?

1 comment:

Tim Barrass said...

Use ~p for better formatted printing -- and conversion from ASCII to strings.