Hi, David,

David Hawley wrote:
> 
> I come from the perl, tcl world where hashes are more like
> array indicies.  In rebol, it seems that I can build a hash
> list, of some arbitrary values, but cannot associate keys
> with data. Am I missing soemthing?
> 
> is in perl $hash{ "joe" } = $joesData
> and $data = $hash{ " joe" }
> 
> can I do something like this in REBOL?
> 

You can do this in REBOL:

    favoriteLanguage:
    [   "Larry"   "Perl"
        "Carl"    "REBOL"
        "Guido"   "Python"
        "Matz"    "Ruby"
        "Richard" "LISP"
    ]

and then

    >> print select favoriteLanguage"Guido"
    Python

However, if you want to maintain a dynamic set of associations
it's a bit more work:

    assoc: make object!
    [   data: []
        default: 0
        clear: func [] [data: copy []]
        store: func [k [string!] v [string!] /local pos]
        [   pos: find/skip data k 2
            either found? pos
            [   change next pos v]
            [   append append data k v]
        ]
        fetch: func [k [string!] /local r]
        [   either found? r: select/skip data 2 k [r] [default]]
    ]

used as follows:

    >> favlang: make assoc [default: "INTERCAL"]
    >> favlang/fetch "David"
    == "INTERCAL"
    >> favlang/store "David" "REBOL"
    == ["David" "REBOL"]
    >> favlang/store "Bjarne" "c++"
    == ["David" "REBOL" "Bjarne" "c++"]
    >> favlang/store "Edsger" "Mathematics"
    == ["David" "REBOL" "Bjarne" "c++" "Edsger" "Mathematics"]
    >> favlang/fetch "David"
    == "REBOL"
    >> favlang/fetch "Edsger"
    == "Mathematics"

Both blocks and hashes can be used with SELECT and FIND (and other
access/manipulation functions as well).  Hashes use a hash-coding
scheme (internally) to speed the searching.

You may be wondering about the /SKIP above.  The reason is that
REBOL by default treats blocks and hashes as ordered collection
of *single*values* which means that one could also say

    >> select favlang/data "REBOL"
    == "Bjarne"

to conclude that REBOL's favorite programming language is Bjarne!

The /SKIP refinement tells FIND, SELECT, et al, to treat the
first argument as a collection of n-tuples, where n is the last
argument.  When we say  SELECT/SKIP block val 2  we're asking
SELECT to consider only the first value of every *pair* of
entries, so that we get

    >> select/skip favlang/data "Edsger" 2
    == ["Mathematics"]
    >> select/skip favlang/data "REBOL" 2
    == none

which is more likely what you'd expect, coming from Perl.  You
can, of course, use other tuple sizes than 2, as in

    guruData:
    [   "Edsger" "Dijkstra" "UT Austin"
        "Don"    "Knuth"    "Stanford"
        "Tony"   "Hoare"    "Oxford"
        "David"  "Gries"    "Cornell"
    ]

which then can be treated as triples of data via

    >> select/skip guruData "Tony" 3
    == ["Hoare" "Oxford"]

(Notice that the remainder of the triple is returned as a block.)
Even though

    >> find/skip guruData "Don" 3
    == [
        "Don" "Knuth" "Stanford"
        "Tony" "Hoare" "Oxford"
        "David" "Gries" "Cornell"
    ]

succeeds, notice that

    >> find/skip guruData "Oxford" 3
    == none

fails, since "Oxford" doesn't *begin* any triple of values.

HTH!

-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" ;
-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to