count characters. (Was: Simple things should be simple to do ?)
[1/7] from: tooki::widebay::net::au at: 16-Nov-2000 16:05
Hi Guys,
One last version. Since I believe a function should always return a value,
here is the final version (for now) of the character counting function:
REBOL []
count-char: func [
{
This function counts the number of occurrances of each character in
string str, and returns a printable block with the results.
}
str [string!]
/local count look
][
count: make block! 0
foreach char str [
either look: find count char [
change (next look) ((second look) + 1)
][
append count reduce [char 1 "^/"]
]
]
return count
]
Regards,
Bard
[2/7] from: al:bri:xtra at: 16-Nov-2000 21:26
Bard wrote:
> REBOL []
I'd write a bit more stuff in the header.
> count-char: func [
> {
<<quoted lines omitted: 3>>
> str [string!]
> /local count look
Instead of using '/local, I'd use 'function instead of 'func. This is
because it makes it clearer what are local variables. It can be easy to
mistype and put in "locale" instead. Using 'function makes locals obvious.
> ][
> count: make block! 0
> foreach char str [
> either look: find count char [
I'd use this instead:
either found? look: find count char [
This is to help make it clear what you're looking for.
> change (next look) ((second look) + 1)
> ][
<<quoted lines omitted: 3>>
> return count
> ]
I hope that helps.
Andrew Martin
Rebol "purist"...
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[3/7] from: brett:codeconscious at: 16-Nov-2000 20:22
> So, let's see if anyone else comes up with even more elegant solutions. I
> love to see other people's code. The ideas some people come up with never
> stop to astound and delight me.
I won't claim my solution to be any more elegant, but just shows another way
of looking at the problem.
I limit my solution to only handling strings and I know at that Rebol at the
moment only has 8bit characters. So I can map characters to array positions.
So the counting part becomes the smallest part of the code and potentially
the fastest bit.
The array structure might be a useful result if you were doing some sort of
batch analysis so I leave it available to be returned using a refinement.
character-count: function [
"Counts characters in a string."
string [string!]
/positional "Return an array of counts - position indicates
character."
] [count-array slot c result-block char-count] [
; Do the counting
count-array: array/initial 256 0
foreach c string [
slot: add 1 to-integer c
poke count-array slot (add 1 pick count-array slot)
]
; Returns the result in desired format
either positional [
RETURN count-array
] [
result-block: copy []
for i 1 256 1 [
if greater? c: pick count-array i 0 [
insert tail result-block reduce [to-char subtract i 1 c]
]
]
RETURN result-block
]
]
Example
>> str: "sdfsdfsdfsdfsdfsd"
== "sdfsdfsdfsdfsdfsd"
>> print mold character-count str
[#"d" 6 #"f" 5 #"s" 6]
Regards
Brett
[4/7] from: tooki:widebay:au at: 16-Nov-2000 20:54
Hi Guys,
I have integrated the suggestions of Andrew, and this is the end-result.
Time to give this one a rest, and move on to more daunting stuff (anyone
done that XML-to-HTML-using-stylesheets thingie yet?).
REBOL [
Title: "Counting chars in a string"
File: %count-char.r
Date: 16-November-2000
Purpose: {
To count the number of occurences of each character in
a string.
}
Usage: {count-char string!}
Notes: {
Implemented after some very useful suggestions by the REBOL
mailing list people. Thanx guys!
}
History: [
16-November-2000 "A version I can live with!"
]
]
count-char: function [
{
This function counts the number of occurrences of each character in
string str, and returns a printable block with the results.
}
str [string!]
][
count
look
][
count: make block! 0
foreach char str [
either found? look: find count char [
change (next look) ((second look) + 1)
][
append count reduce [char 1 "^/"]
]
]
return count
]
Bard
[5/7] from: tooki:widebay:au at: 16-Nov-2000 15:27
Hi All,
I've found the answer to my own question:
> One thing though: isn't there a more elegant way of doing the
> append(append(append count char) 1) "^/") stuff?
Turns out you can do:
append count reduce [char 1 "^/"]
with the same result.
The whole 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 count reduce [char 1 "^/"]
]
]
print count
]
It does do the trick:
>> count-char "aaabbbccddddddd"
a 3
b 3
c 2
d 7
So, let's see if anyone else comes up with even more elegant solutions. I
love to see other people's code. The ideas some people come up with never
stop to astound and delight me.
Bard
[6/7] from: al:bri:xtra at: 17-Nov-2000 16:20
> Time to give this one a rest, and move on to more daunting stuff (anyone
done that XML-to-HTML-using-stylesheets thingie yet?).
No. I intend to use eText to XML/XHTML/HTML and not bother to inflict markup
on people. Instead, I'll use white space intelligently along with Rebol
embedded in the script (in a very nice way), to generate web pages.
Andrew Martin
Beyond Rebol Server Pages...
ICQ: 26227169
http://members.nbci.com/AndrewMartin/
[7/7] from: tooki:widebay:au at: 17-Nov-2000 14:56
I'd sure love to see that in action, for I'm a bit lost at the moment as to
which road to follow. For instance: I could probably dazzle my boss if I
could show him how I translate the company's XML pages into mult-style
REBOL/VIEW displays as well as in HTML pages using different stylesheet
plug-ins. At the moment the company uses XSL and JSP servlets to do the XML
to HTML conversion, and I find it very confusing. Remember, I'm new to all
this. I used to do 'simple' ASP/JSP/VBScript/JavaScript before they decided
to dump all this new-fangled stuff on me (not true, really, I tipped them on
SGML and later XML a few years ago, but I did not have to time to keep up
with all the technicalities involved. So i'ts my own ghost that's haunting
me now ;-)
Bard
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted