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

Block/array manipulation

 [1/8] from: chris:ross-gill at: 15-Oct-2001 18:45


Hi Mat & Carl,
> Hmmm. A quick test of that didn't work for me. However, there's a > word to do that. It's called 'unique. (: ... > > >> unique stuff > == ["fire" "water" "air"]
Knew there was a more suitable word than 'union. Anyway, had a go refining the function. This one is better because: o It uses less words. o It works with blocks that include integers. Which itself is interesting - Try this at the console: x: [1] x: block-stats x ; keep repeating this line Try starting 'x at [1 2] or [1 2 3]. They all come to the same conclusion. (well, I found it interesting :o) - Chris -- REBOL [] block-stats: func [ in-blk [block!] /local num num-blk out-blk ][ out-blk: unique in-blk num-blk: copy [] loop length? out-blk [append num-blk 0] foreach item in-blk [ num: index? find out-blk item change back skip num-blk num num-blk/:num + 1 ] while [not tail? out-blk][ insert next out-blk first num-blk out-blk: skip out-blk 2 num-blk: next num-blk ] head out-blk ]

 [2/8] from: joel:neely:fedex at: 15-Oct-2001 17:43


Hi, Mat, Mat Bettinson wrote:
...
> Let's take a block of stuff; > > Stuff: make block! ["fire" "water" "air" "water" "water" "air"] >
...
> The question is, say I wanted to do this but count each instance > of the words as they are subsequently found? IE I could somehow > tell that water was found 3 times and air was found twice. >
Given ...
>> stuff: ["fire" "water" "air" "water" "water" "air"]
== ["fire" "water" "air" "water" "water" "air"] ... the non-duplicated version can be computed by ...
>> unique stuff
== ["fire" "water" "air"] ... and the counting version can be computed by ... stuffstats: func [b [block!] /local result where] [ result: copy [] foreach item b [ either found? where: find result item [ change next where 1 + second where ][ append result reduce [item 1] ] ] result ] ... as in ...
>> stuffstats stuff
== ["fire" 1 "water" 3 "air" 2] -jn- -- This sentence contradicts itself -- no actually it doesn't. -- Doug Hofstadter joel<dot>neely<at>fedex<dot>com

 [3/8] from: joel:neely:fedex at: 15-Oct-2001 21:28


Hi, again, Mat, Joel Neely wrote:
> stuffstats: func [b [block!] /local result where] [ > result: copy []
<<quoted lines omitted: 7>>
> result > ]
Of course, the above version only works if the original block excludes just the right combination of small integers... :-/ This version corrects for that deficiency:
>> stuff: [1 2 3 2 1 4 1 2 3 1]
== [1 2 3 2 1 4 1 2 3 1] stuffstats: func [b [block!] /local result where] [ result: copy [] foreach item b [ either found? where: find/skip result item 2 [ change next where 1 + second where ][ append result reduce [item 1] ] ] result ] as in
>> stuffstats stuff
== [1 4 2 3 3 2 4 1] Finally, a version that avoids the data type issue and give the results back in a nice order: stuffstats: func [b [block!] /local c i j result] [ result: copy [] c: sort copy b while [not tail? c] [ i: first c j: 0 while [all [not tail? c i = first c]] [ j: j + 1 c: next c ] append result reduce [i j] ] result ] ... with both integers ...
>> stuffstats stuff
== [1 4 2 3 3 2 4 1] ... and strings.
>> stuff: ["fire" "water" "air" "water" "water" "air"]
== ["fire" "water" "air" "water" "water" "air"]
>> stuffstats stuff
== ["air" 2 "fire" 1 "water" 3] -jn- -- ; sub REBOL {}; sub head ($) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} print head reverse despam "moc:xedef#yleen:leoj" ;

 [4/8] from: mat::b::codeplay::com at: 15-Oct-2001 16:17


Folks, Here's a simple thing which I've needed to do quite a bit of, but couldn't quite figure out how you'd do it in Rebol so tended to do things the long way. Let's take a block of stuff; Stuff: make block! ["fire" "water" "air" "water" "water" "air"] Now the object of the excersize is to to build block with all of the unique values. That bit is easy; foundstuff: make block! [] foreach bitofstuff stuff [ if found? find foundstuff bitofstuff [ append foundstuff bitofstuff ] ] After this, all of the unique values are loaded into the 'foundstuff' block. The question is, say I wanted to do this but count each instance of the words as they are subsequently found? IE I could somehow tell that water was found 3 times and air was found twice. This is where my rudimentary grasp of Rebol fails me. :) Regards, Mat Bettinson Codeplay Tel: +44 (0)20 7482 3382 140-142 Kentish Town Rd, London, NW1 9QB http://www.codeplay.com

 [5/8] from: chris:ross-gill at: 15-Oct-2001 15:19


Hi Mat,
> Here's a simple thing which I've needed to do quite a bit of, but > couldn't quite figure out how you'd do it in Rebol so tended to do
<<quoted lines omitted: 14>>
> the words as they are subsequently found? IE I could somehow tell that > water was found 3 times and air was found twice.
I think this function addresses your needs, but I'm sure it can be further refined... usage - unique-stuff: block-stats stuff - Chris -- REBOL [] block-stats: func [ in-blk [block!] /local count mark work-blk out-blk ][ set 'count 0 out-blk: copy work-blk: union copy in-blk [] foreach item work-blk [ while [mark: find in-blk item] [ count: count + 1 in-blk: next mark ] in-blk: head in-blk insert next find out-blk item count set 'count 0 ] return out-blk ]

 [6/8] from: jelinem1:nationwide at: 15-Oct-2001 14:55


; I think you forgot the 'not in your test: ;------------------------------------------------------- Stuff: make block! ["fire" "water" "air" "water" "water" "air"] foundstuff: make block! [] forall stuff [ if not found? find foundstuff (pick stuff 1) [ append foundstuff (pick stuff 1) ] ] ;------------------------------------------------------- ; Not sure in what form you want to the counts to be, so I've created a second array whose entries correspond with the foundstuff array: ;------------------------------------------------------- Stuff: make block! ["fire" "water" "air" "water" "water" "air"] foundstuff: make block! [] countstuff: make block! [] forall stuff [ either not found? find foundstuff (pick stuff 1) [ append foundstuff (pick stuff 1) append countstuff 1 ][ pos: index? find foundstuff (pick stuff 1) count-here: at countstuff pos count-here/1: 1 + count-here/1 ] ] ;------------------------------------------------------- [Michael Jelinek] Mat Bettinson <[mat--b--codeplay--com]> Sent by: [rebol-bounce--rebol--com] 10/15/01 10:17 AM Please respond to rebol-list T To: Jason Cunliffe <[rebol-list--rebol--com]> cc: bcc: Subject: [REBOL] Block/array manipulation Folks, Here's a simple thing which I've needed to do quite a bit of, but couldn't quite figure out how you'd do it in Rebol so tended to do things the long way. Let's take a block of stuff; Stuff: make block! ["fire" "water" "air" "water" "water" "air"] Now the object of the excersize is to to build block with all of the unique values. That bit is easy; foundstuff: make block! [] foreach bitofstuff stuff [ if found? find foundstuff bitofstuff [ append foundstuff bitofstuff ] ] After this, all of the unique values are loaded into the 'foundstuff' block. The question is, say I wanted to do this but count each instance of the words as they are subsequently found? IE I could somehow tell that water was found 3 times and air was found twice. This is where my rudimentary grasp of Rebol fails me. :) Regards, Mat Bettinson Codeplay Tel: +44 (0)20 7482 3382 140-142 Kentish Town Rd, London, NW1 9QB http://www.codeplay.com

 [7/8] from: carl:cybercraft at: 16-Oct-2001 8:54


On 16-Oct-01, Mat Bettinson wrote:
> Folks, > Here's a simple thing which I've needed to do quite a bit of, but
<<quoted lines omitted: 10>>
> ] > ]
Hmmm. A quick test of that didn't work for me. However, there's a word to do that. It's called 'unique. (: ...
>> unique stuff
== ["fire" "water" "air"]
> After this, all of the unique values are loaded into the > 'foundstuff' block. > The question is, say I wanted to do this but count each instance of > the words as they are subsequently found? IE I could somehow tell > that water was found 3 times and air was found twice. > This is where my rudimentary grasp of Rebol fails me. :)
Check out the related words to 'unique in the Core Guide. 'difference and such. A mix of them might give you what you want. (Sory - running late for work at the moment. :)
> Regards, > Mat Bettinson > Codeplay > Tel: +44 (0)20 7482 3382 > 140-142 Kentish Town Rd, London, NW1 9QB > http://www.codeplay.com
-- Carl Read

 [8/8] from: lmecir:mbox:vol:cz at: 16-Oct-2001 21:48


Hi Joel,
> Joel Neely wrote: > >
<<quoted lines omitted: 45>>
> result > ]
Isn't the latter solution much faster than the former one? Cheers Ladislav

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