[REBOL] Re: Andrews Map: (Examples)
From: joel:neely:fedex at: 18-Feb-2003 17:03
Hi, Tim,
We've kicked this one around before; see
http://www.escribe.com/internet/rebol/m13736.html
and the related thread for more discussion. However, I'll give
a couple of quick examples below.
Tim Johnson wrote:
> Does any one have any examples of using it [map] ...
>
Here's a (simplified) version of MAP that I've been using for quite
a while, along with another handy utility:
map: function [
f [any-function!] b [block!] /all
][
result item
][
result: make block! length? b
foreach val b [
item: f val
if any [found? item all] [
append/only result item
]
]
result
]
ident: func [f [any-function!] x [any-type!]] [
if f x [x]
]
First, a couple of simple illustrations:
>> map func [x] [x * x] [0 1 2 3 4 5]
== [0 1 4 9 16 25]
MAP abstracts out the notion of "do this to all of those and give
me all of the results" so that we don't have to hand-code the loop
boilerplate over and over.
>> map func [x] [ident :even? x] [0 1 2 3 4 5]
== [0 2 4]
IDENT evaluates to its second argument only if that value satisfies
the first argument. My version of MAP doesn't include NONE in the
results (unless you set the /ALL refinement) so this essentially
can be read as "give me back only the values that satisfy this test".
In a teaching situation, just to give one more specific application
example, we could have a function that translates from a numerical
(percentage) score to a letter grade:
pct2grade: func [p [number!] /local lowbounds letters] [
lowbounds: [95 85 75 60 0]
letters: ["A" "B" "C" "D" "F"]
for i 1 length? lowbounds 1 [
if lowbounds/:i <= p [
return letters/:i
]
]
last letters
]
(In real life, I'd use an object, but I'm trying to keep to brief
examples here.)
We can also have a function that takes a total possible number of
points and the number of points earned by a student, returning a
percentage score (with a lower bound of zero!)
raw2pct: func [t [number!] s [number!]] [
max 0 0.1 * to-integer 0.5 + 1000.0 * s / t
]
We can stick a block of raw scores onto one (nested) expression:
map :pct2grade map func [x][raw2pct 175 x] [
115 180 33 159 168 144
]
and get the grades for the class
== ["D" "A" "F" "B" "A" "C"]
The real point of MAP to my way of thinking is that it continues
the progression we started with structured programming; we can
use a WHILE or FOR expression to directly state that we want
something repeatedly evaluated under specific circumstances,
without having to think about bolting together some more primitive
concepts.
Likewise, MAP allows us to express directly that we want to
apply a function to a collection of values and get all of the
results, without having to bolt together the looping and appending
by hand every time.
HTH!
-jn-
--
----------------------------------------------------------------------
Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446
Atlanta, Ga. - Scientists at the Centers for Disease Control today
confirmed that hoof-and-mouth disease cannot be spread by Microsoft's
Outlook email application, believed to be the first time the program
has ever failed to propagate a major virus.