Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

nforeach

 [1/6] from: g:santilli:tiscalinet:it at: 22-Jul-2003 13:12


Hello all, it often happens to me to have to iterate in parallel over two or more series. Today I thought it was the time to solve the issue once and for all with a specific function. :) Note: this is rather a QAD implementation. It surely needs improvements. It works this way:
>> nforeach [a [1 2 3] b [4 5 6]] [print [a b]]
1 4 2 5 3 6 It also handles more complicated cases:
>> w: 'c b: [d e] nforeach [file read %./ [a b] [1 2 3 4 5 6] :w [x y z] :b [9 8 7 6 5]] [print [file a b c d e]]
desktop/ 1 2 x 9 8 edit-prefs.r 3 4 y 7 6 license.key 5 6 z 5 none local/ none none none none none prefs.r none none none none none public/ none none none none none rebol-1.2.1.exe none none none none none rebol-link.exe none none none none none rebol.exe none none none none none rebol.r none none none none none user.r none none none none none view1210031.exe none none none none none viewtop1200.zip none none none none none Let me know what you think. context [ invalid: func [arg] [throw make error! join [script invalid-arg] :arg] ceil: func [num [number!]] [ either num > num: to integer! num [num + 1] [num] ] set 'nforeach func [[catch] args [block!] body [block!] /local bargs words end word] [ bargs: head clear next [body] words: clear [ ] end: 0 while [not tail? args] [ word: pick args 1 if not any [word? :word block? :word all [get-word? :word any [word? word: get :word block? :word]]] [ invalid :word ] use [series] [ set [series args] do/next next args if not series? :series [ invalid :series ] insert tail words word either block? word [ repeat j length? word [ insert insert insert insert tail bargs [pick :series i - 1 *] length? word '+ j ] end: max end ceil divide length? :series length? word ] [ insert tail bargs [pick :series i] end: max end length? :series ] ] ] if any [empty? words empty? bargs] [return none] body: func words body repeat i end bargs ] ] Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [2/6] from: greggirwin:mindspring at: 22-Jul-2003 8:33


Thanks Gabriele! It's a good week for cool functions it seems. :) --Gregg

 [3/6] from: rotenca:telvia:it at: 22-Jul-2003 18:21


> Let me know what you think.
Good! But you must copy bargs for recursion. --- Ciao Romano

 [4/6] from: AJMartin:orcon at: 23-Jul-2003 18:57


Gabriele wrote:
> It works this way: > > >> nforeach [a [1 2 3] b [4 5 6]] [print [a b]]
I've been wanting something like this for a while. Thank you, Gabriele! I think I might like it better like this:
>> nforeach [a b] [[1 2 3] [4 5 6]] [print [a b]]
That's because when working with a table of data (rows and columns of data) it might be easier to write things like: Table_Header: [a b] Table_Rows: [ [1 4] [2 5] [3 6] ]
>> transpose Table_Rows
== [[1 2 3] [4 5 6]] nforeach Table_Header transpose Table_Data [print [a b]] Andrew J Martin ICQ: 26227169 http://www.rebol.it/Valley/ http://Valley.150m.com/

 [5/6] from: g:santilli:tiscalinet:it at: 23-Jul-2003 9:45


Hi Romano, On Tuesday, July 22, 2003, 6:21:03 PM, you wrote: RPT> But you must copy bargs for recursion. You're right. There are other things it does not handle (should have [throw] for returning from the body, and probably use Ladislav's tfunc to avoid all of the subtle issues with these kind of functions). I'll leave all this to the reader as an exercise. ;-) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [6/6] from: g:santilli:tiscalinet:it at: 23-Jul-2003 10:23


Hi Andrew, On Wednesday, July 23, 2003, 8:57:53 AM, you wrote: AJM> I think I might like it better like this:
>>> nforeach [a b] [[1 2 3] [4 5 6]] [print [a b]]
Ironicly, that way you'd need NFOREACH inside NFOREACH... ;-) (Of course, if you only support the case of one word per series, it gets simple enough. But see below, if you want to use it on tables.) AJM> Table_Header: [a b] AJM> Table_Rows: [ AJM> [1 4] AJM> [2 5] AJM> [3 6] AJM> ]
>>> transpose Table_Rows
AJM> == [[1 2 3] [4 5 6]] AJM> nforeach Table_Header transpose Table_Data [print [a b]] Hmm, I would do this as: foreach-row: func [table-header table-rows body] [ table-header: use table-header reduce [table-header] bind body table-header/1 ; you might want to use bind/copy ; and check for an empty table-header foreach row table-rows [ set table-header row do body ] ] (untested) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/