Simple things should be simple to do ?
[1/5] from: mdb:gci at: 15-Nov-2000 15:19
REBOL/View 0.10.38.3.1 2-Oct-2000
Copyright 2000 REBOL Technologies. All rights reserved.
>> str: "sdfsdfsdfsdfsdfsd"
== "sdfsdfsdfsdfsdfsd"
>> counts: copy []
== []
>> foreach char str [either none? find counts char [append counts
reduce [char 1]] [
[ x: (index? find counts char) + 1
[ y: (pick counts x) + 1
[ poke counts x y]]
== [#"s" 6 #"d" 6 #"f" 5]
>>
>> foreach [a b] counts [print [a " " b]]
s 6
d 6
f 5
Hello All,
The code above prints out for each unique character in str, the number
of times it occurs. Very simple and works just fine, but it isn't very
Rebolly. I had to do the Find twice and i don't like all the code
involved in adding 1 to the count.
Any suggestions to improve it?
TIA Mike.
[2/5] from: larry:ecotope at: 15-Nov-2000 17:19
Hi Michael
The UNIQUE function in REBOL is handy for this sort of thing. Here is my
solution to your question:
count: func [x /local count][
foreach ux unique x [
count: 0
foreach item x [
if item = ux [count: count + 1]
]
print [ux count]
]
]
Example:
>> str: "sdfsdfsdfsdfsdfsd"
== "sdfsdfsdfsdfsdfsd"
>> count str
s 6
d 6
f 5
Perhaps others can find a more elegant solution?
Cheers
-Larry
[3/5] from: tooki:widebay:au at: 16-Nov-2000 12:35
Hi Michael,
I'm rather new to this great language, but I've given it a try. Just before
sending this I saw the solution of Larry Palmiter , which is more elegant
than mine, but I would like to post it anyway, to see if anyone wants to
comment on my style. I really want to improve myself, so: come on, guys,
shoot at me!
count-char: func [
str [string!]
/local count look
][
count: []
foreach char str [
either look: find count char [
change next look (second look) + 1
][
append (append (append count char) 1) "^/"
]
]
print count
]
>> count-char "abcdefhhjhjeeeehjhjjhe"
a 1
b 1
c 1
d 1
e 6
f 1
h 6
j 5
Bard
Michael wrote:
[4/5] from: larry:ecotope at: 15-Nov-2000 19:21
Hi Bard
Good work! But there is one small problem with your code. If you execute
your function a second or third time, it will produce incorrect answers. If
you repeat it on the same string, the counts will double each time. You can
fix this by defining count like this:
count: copy []
or
count: make block! 0
The reason is that series literals in a function "remember" all previous
modifications. You can see this by doing
source count-char
after each repetion. There is a short discussion of this issue in the new
Core manual available from RT.
Cheers
-Larry
[5/5] from: tooki:widebay:au at: 16-Nov-2000 14:23
Hi Larry,
Thanks for your correction. The code now reads:
count-char: func [
str [string!]
/local count look
][
count: make block! 0
foreach char str [
either look: find count char [
change next look (second look) + 1
][
append (append (append count char) 1) "^/"
]
]
print count
]
And it does work. So I am happy! ;-)
One thing though: isn't there a more elegant way of doing the
append(append(append ...))) stuff?
Thanx once more for your feedback, I'm learning a lot just by looking
through the mailing list.
Bard