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