Jump to content

Rebol Programming/map-each

From Wikibooks, open books for an open world

USAGE:

[edit | edit source]
MAP-EACH 'word data body /into output 

DESCRIPTION:

[edit | edit source]

Evaluates a block for each value(s) in a series and returns them as a block.

MAP-EACH is a function value.

ARGUMENTS:

[edit | edit source]
  • word -- Word or block of words to set each time (local) (Type: word block)
  • data -- The series to traverse (Type: block)
  • body -- Block to evaluate each time (Type: block)

REFINEMENTS:

[edit | edit source]
  • /into -- Collect into a given series, rather than a new block
    • output -- The series to output to (Type: any-block any-string)

(SPECIAL ATTRIBUTES)

[edit | edit source]
  • throw
  • catch

SOURCE CODE

[edit | edit source]
map-each: func [
    {Evaluates a block for each value(s) in a series and returns them as a block.} 
    [throw catch] 
    'word [word! block!] "Word or block of words to set each time (local)" 
    data [block!] "The series to traverse" 
    body [block!] "Block to evaluate each time" 
    /into {Collect into a given series, rather than a new block} 
    output [any-block! any-string!] "The series to output to" 
    /local init len x
][
    if empty? data [return any [output make block! 0]] 
    word: either block? word [
        if empty? word [throw make error! [script invalid-arg []]] 
        copy/deep word
    ] [reduce [word]] 
    word: use word reduce [word] 
    body: bind/copy body first word 
    init: none 
    parse word [any [word! | x: set-word! (
                unless init [init: make block! 4] 
                insert insert insert tail init first x [at data] index? x 
                remove x
            ) :x | x: skip (
                throw make error! reduce ['script 'expect-set [word! set-word!] type? first x]
            )]] 
    len: length? word 
    unless into [output: make block! divide length? data max 1 len] 
    until [
        set word data do init 
        unless unset? set/any 'x do body [output: insert/only output :x] 
        tail? data: skip data len
    ] 
    also either into [output] [head output] (
        set [word data body output init x] none
    )
]