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

En Masse block operations

 [1/8] from: tim:johnsons-web at: 16-Oct-2001 9:25


Hello All: I would like to apply the same operation to all members of a nested block. ;Example: blk: [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] blk: do-all blk next ; set all members to next element ;result sought:
>>[[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"]
blk: do-all blk head ; set all members to head ; result sought:
>>[[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
; I've started by this simple function, which is not doing just ; what I want: REBOL[] do-all: func[blk[block!] ][ ;cmd[word!] foreach member blk[ if series? member[ member: next member print mold member ] ] blk ] test: [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] print mold do-all test ;and I get
>> do %sample.r
Script: "Untitled" (none) [2 3 4] [6 7 8] [10 11 12] [14 15 16 17] ne [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] TIA -- Tim Johnson <[tim--johnsons-web--com]> http://www.johnsons-web.com

 [2/8] from: joel:neely:fedex at: 16-Oct-2001 12:05


Hi, Tim, Tim Johnson wrote:
> Hello All: > I would like to apply the same operation to all members
<<quoted lines omitted: 4>>
> ;result sought: > >>[[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"]
Sounds like a job for MAP to me...
>> blk: [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] ... then ... map: function [[catch] b [block!] f [function!] /all] [r v] [ r: make block! length? b foreach c b [ if any [found? v: do [f c] all] [append/only r v] ] r ] ... and, finally ...
>> map blk func [s][next s]
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"] ... or ...
>> x: map blk func [s] [next s]
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"]
>> x: map x func [s] [next s]
== [[3 4] [7 8] [11 12] [15 16 17] "e"]
>> map x func [s] [head s]
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] HTH! -jn- -- This sentence contradicts itself -- no actually it doesn't. -- Doug Hofstadter joel<dot>neely<at>fedex<dot>com

 [3/8] from: greggirwin:mindspring at: 16-Oct-2001 11:18


Hi Tim, I think map will do what you want. ; Larry Palmiter's version but Ladislav and Andrew also have them map: func [fn blk args /local result][ result: copy [] repeat el blk [append/only result fn :el args] return result ]
>> test: [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
>> map :next test none
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"]
>> map :head test none
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] --Gregg

 [4/8] from: ryanc:iesco-dms at: 16-Oct-2001 10:27


Dont use 'foreach. 'Foreach makes a copy of the value, bungling your method. Use 'forall or 'repeat. I like using 'repeat for this sort of thing because I can do it without the awkward [block: head block] at the end. Also you might want to use 'block? instead of 'series? to validate whether an operation is warranted. Many other data values are considered a series...
>> series? "abc"
== true
>> series? ftp://bob.jones.com
== true
>> series? [ned--none--com]
== true
>>
--Ryan Tim Johnson wrote:
> Hello All: > I would like to apply the same operation to all members of a nested block.
<<quoted lines omitted: 37>>
> [rebol-request--rebol--com] with "unsubscribe" in the > subject, without the quotes.
-- Ryan Cole Programmer Analyst www.iesco-dms.com 707-468-5400

 [5/8] from: tim:johnsons-web at: 16-Oct-2001 11:00


On Tue, Oct 16, 2001 at 11:18:05AM -0600, Gregg Irwin wrote:
> Hi Tim, > > I think map will do what you want.
Yes indeed. It's exactly what I want. :>) ==>>I note a bonus: I think I'm seeing how one passes a function as an argument. Thank you Gregg
> ; Larry Palmiter's version but Ladislav and Andrew also have them > map: func [fn blk args /local result][
<<quoted lines omitted: 13>>
> [rebol-request--rebol--com] with "unsubscribe" in the > subject, without the quotes.
-- Tim Johnson <[tim--johnsons-web--com]> http://www.johnsons-web.com

 [6/8] from: tim:johnsons-web at: 16-Oct-2001 11:12


On Tue, Oct 16, 2001 at 12:05:21PM -0500, Joel Neely wrote:
> Sounds like a job for MAP to me... > >> blk: [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
<<quoted lines omitted: 17>>
> >> map x func [s] [head s] > == [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
Joel: Thanks a lot! But now I have another question: I see Ryan's opinion not to use 'foreach..... Could you comment on his opinion on this. (I've seen references to a foreach "bug" and I almost never use it myself.) Regards Tim

 [7/8] from: joel:neely:fedex at: 16-Oct-2001 14:09


Hi, Tim, Tim Johnson wrote:
> I see Ryan's opinion not to use 'foreach..... > Could you comment on his opinion on this. > > (I've seen references to a foreach "bug" and > I almost never use it myself.) >
AFAIK there's no bug involved, but it is possible to misunderstand what FOREACH (and REPEAT, for that matter) are doing. Here's your original sample block:
>> blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] Let's go through it with FOREACH...
>> foreach item blk [print item: next item]
2 3 4 6 7 8 10 11 12 14 15 16 17 ne ... and then look at the block again ...
>> blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] The block itself is unchanged. The (local) word ITEM was set to each value in the block in turn. This means that the expression item: next item in the above code is changing the position to which ITEM refers, but not changing the (explicit, literal) series reference that is in each position of BLK. The same thing happens if you use REPEAT as follows:
>> repeat item blk [print item: next item]
2 3 4 6 7 8 10 11 12 14 15 16 17 ne
>> blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] The point is that if you want to mutate the values in BLK, you're going to have to do one of two things: 1) work directly with the references in BLK (or an alternate reference to BLK), or 2) compute a new block based on the old values in BLK and set BLK to refer to that new block. The first alternative could be written as
>> forall blk [ blk/1: next blk/1 ] blk: head blk
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"]
>> blk
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"] and could be undone by
>> forall blk [blk/1: head blk/1] blk: head blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] The second alternative could be coded in-line or done via MAP, as discussed in my prior email.
>> loop 5 [print mold blk: map blk func [s] [next s]]
[[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"] [[3 4] [7 8] [11 12] [15 16 17] "e"] [[4] [8] [12] [16 17] ""] [[] [] [] [17] ""] [[] [] [] [] ""]
>> blk: map blk func [s] [head s]
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] In any event, I'm not aware of a FOREACH "bug" and use it all the time. HTH! -jn- -- This sentence contradicts itself -- no actually it doesn't. -- Doug Hofstadter joel<dot>neely<at>fedex<dot>com

 [8/8] from: ingo:2b1 at: 16-Oct-2001 21:03


Hi Tim, by now you've heard about map more than once, one other possibility would be, e.g. Once upon a time Tim Johnson spoketh thus:
> Hello All: > I would like to apply the same operation to all members of a nested block.
<<quoted lines omitted: 6>>
> ; result sought: > >>[[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"]
>> forall blk [if block? blk/1 [ blk/1: next blk/1 ]]
== []
>> blk: head blk
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "one"]
>> forall blk [if block? blk/1 [ blk/1: head blk/1 ]] blk: head blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] kind regards, Ingo

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted