Counting chars (was Simple things should be simpl e to do ?)
[1/2] from: rsnell::webtrends::com at: 16-Nov-2000 16:15
It's really the hash that makes it easy. I have an
associative array (that I call a map - much easier to type)
that I use all the time. Given my map, my count routine
becomes:
s: "sdfsdfsdfsdfsdfsd"
m: make map! []
foreach c s [
m/set c ((to-integer m/get c) + 1)
]
repeat i m/length? [
print [(first at m/keys i) (first at m/vals i)]
]
s 6
d 6
f 5
Almost as easy as Perl if you don't take into account the code for the map
(which I have not included).
If you don't have a map (associative array) in your toolbox, get one.
It can make some functions a lot easier. If anyone wants I can post
the source to mine but others have been posted by better Rebolers
at various times.
Rodney
[2/2] from: rsnell:webtrends at: 17-Nov-2000 10:18
Here is my map. There a couple of ini methods that I use to
support ini files (map of maps). I'm sure it can be improved in many
ways so caveat emptor...
-------------------------------------------------------
REBOL [Title: "Map Object"]
map!: make object!
[
name: copy ""
keys: make block! 20
vals: copy []
length?: func[] [system/words/length? keys]
empty?: func [] [system/words/empty? head keys]
clear: func [] [keys: make block! 20 vals: copy [] name: copy ""]
get: func [k /default def] [return either default [map-get/default
self k def] [map-get self k]]
set: func [k v] [return map-set self k v]
remove: func [k] [return map-remove self k]
load-ini: func [] [clear return map-load-ini name]
save-ini: func [] [map-save-ini self name]
]
map-get: func
[
"return value of key - or default if no key and default given - or
none"
map "map"
key "key"
/default "default value to return if key isn't found"
def "default value"
/local s
]
[
s: find map/keys key
either s
[
return first at map/vals index? s
]
[
either default [return def] [return none]
]
]
map-set: func
[
"adds new key/value or changes value of existing key"
map "map"
key "key"
val "val"
/local s
]
[
s: find map/keys key
either s
[
change at map/vals index? s reduce val
return true
]
[
append map/keys reduce key
append map/vals reduce val
return false
]
]
map-remove: func
[
"removes key/value from map"
map "map"
k "key"
/local p v
]
[
either none? p: find map/keys k
[
return false
]
[
k: pick map/vals p: index? p
remove at map/keys p
remove at map/vals p
return true
]
]
map-load-ini: func
[
"loads a map from an ini file"
inifile [file! string!] "ini file to read from"
/local l secname key val lines gm m
]
[
if not exists? to-file inifile [return none]
lines: read/lines to-file inifile
gm: make map! [name: to-string inifile]
foreach l lines
[
either #"[" = pick l 1
[
parse l [thru "[" copy secname to "]"]
if not (length? secname) = 0
[
m: make map! [name: secname]
map-set gm secname m
]
]
[
trim l
if not (length? l) = 0
[
parse l [copy key to "=" skip copy val to
end]
either all [key val]
[
map-set m trim key trim val
]
[
if key [map-set m trim key ""]
]
]
]
]
return gm
]
map-save-ini: func
[
"saves a map to an ini file"
map "map"
inifile [file! string!] "ini file to save to"
/local str gk gv gkey gval keys vals key val
]
[
str: make string! 5000
gk: map/keys
gv: map/vals
foreach gkey gk
[
print gkey
append str reduce[#"[" gkey #"]" newline]
gval: first gv
keys: gval/keys
vals: gval/vals
gv: next gv
foreach key keys
[
val: first vals
vals: next vals
append str reduce[key "=" val newline]
print [key "=" val]
]
append str newline
]
print "save-ini"
print inifile
either error? try [write to-file inifile str] [return false][return
true]
]