The array command manipulates Tcl's associative arrays (except for standard reading and writing of array entries, which are treated like normal Tcl variables using the ary(key) syntax.)
See http://purl.org/tcl/home/man/tcl8.4/TclCmd/array.htm for the man page description of:
array anymore arrayName searchId array donesearch arrayName searchId array exists arrayName array get arrayName ?pattern? array names arrayName ?mode? ?pattern? array nextelement arrayName searchId array set arrayName list array size arrayName array startsearch arrayName array statistics arrayName array unset arrayName ?pattern?
All array commands require the arrayName rather than the array itself - unlike the list commands (with the only exception of lappend and lset in 8.4).
Note that when referencing an array element, that the element portion is considered a part of the name. Thus, if the array name itself requires {} for variable substituion, then the element reference will too.
That is to say:
array unset {this stuff} set {this stuff(one)} 1 parray {this stuff}
How are Tcl arrays different from what people normally think of arrays? In Tcl, the array is really better termed a hash map (ala perl) or perhaps a [use snobol, awk, python, etc. term here ]. The indexes can be any string, the indexes are not ordered, etc. A Tcl array isn't restricted to indexes of just numbers. Likewise, it isn't straight forward to get things out of a Tcl array in the same order as you put them in. Even if you use a number for putting things into the Tcl array, remember that Tcl is treating it as a random string. Thus you have to factor this in when writing code to pull things out of the array.
A Tcl scalar variable contains a string . That string can have some sort of programmer envisioned data structure encoded into it - see list for one example and keyed list for another.
TclX has keyed lists. NAP has some sort of array/vector data structure.
set array(element) "Value" array set myArray{} ;# Create an empty array
Bruce Hartweg recently wrote in news:comp.lang .tcl:
unset x ; # x doesn't exist at all anymore unset x ; array set x {} ; # x exists as an array but has no elements array unset x ; # available in recent versions # - same results as 2 foreach idx [array names x] { set x($idx) {} } ; # array exists - all the elements still # exist, but values of each element are now # empty
For detailed discussions, see Arrays / hash maps; for many usage examples, A simple database . See also parray.
Thinking about using arrays as sets got me wondering: What is the smallest amount of storage that can be taken up by a value in an array? Assuming the keys are what is important to me, I would want to take up the least amount of storage for the values. So, what's smallest? An integer (or zero specifically)? An empty string? The key itself? --escargo 11/11/2002
Lars H: This is a very tricky question (especially since Tcl does not provide much for Introspection into the matter). I had expected that any value (TclObject) which already exists should yeild the same result, but it seems to matter:
Bytes allocated Code --------------- ---------------- 970752 for {set n 1} {$n<10000} {incr n} {set A($n) [expr 0]} 729088 set zero [expr 0]; for {set n 1} {$n<10000} {incr n} {set A($n) $zero} 729088 for {set n 1} {$n<10000} {incr n} {set A($n) 0} 729088 for {set n 1} {$n<10000} {incr n} {set A($n) {}} 1130496 for {set n 1} {$n<10000} {incr n} {set A($n) $n} 970752 for {set n 1} {$n<10000} {incr n} {set A([format %d $n]) $n}
(These measurements were essentially obtained by comparing the vsize (as reported by ps) of tclsh before and after evaluating the above code, hence it is rather crude.)
escargo: Those last two seem strange! Why would having the pure string as the name make such a difference in the storage? Makes me wonder what this would be.
??????? for {set n 1} {$n<10000} {incr n} {set A($n) [format %d $n]}
Also, isn't there a fence post error here? Shouldn't the range start with set n 0? Otherwise I see 9999 instances being created, not 10,000.
Lars H: And 10000 instances would be more natural than 9999 for what reason? We're just trying to see what's best, and aren't particularly concerned with how good the best are.
As for that mysterious result when the key was used as value, I'm just as surprised as you are. But try it yourself. The code used for obtaining the measurements can be found on Measuring memory usage. I also set up Compact data storage for discussing matters of this kind.
escargo 22 Nov 2002 - I would think that 10000 would be more natural than 9999 just in terms of thinking about averages. I would rather mentally try to divide a number by 10000 than worry about dividing by 9999.
escargo 19 Nov 2002 - Here is another question: What is the most efficient way to determine if the contents of two arrays are the same or different?
If array get had an option to specify the method and order of the results, then a simpler comparison could be done.
(In Icon a table can be turned into a list by its sort function, which can return the results in one of four ways:
This puts the table into a known canonical order. There appears to be no way to know that array get would linearize two arrays in the same way.)
It makes me wish there was an array compare function that could easily answer the question.
Michael A. Cleverly 19 Nov 2002 - Here's an array compare type proc:
proc array-compare {array1 array2} { upvar 1 $array1 foo $array2 bar if {![array exists foo]} { return -code error "$array1 is not an array" } if {![array exists bar]} { return -code error "$array2 is not an array" } if {[array size foo] != [array size bar]} { return 0 } if {[array size foo] == 0} { return 1 } set keys(foo) [lsort [array names foo]] set keys(bar) [lsort [array names bar]] set keys(keys) $keys(foo) if {![string equal $keys(foo) $keys(bar)]} { return 0 } foreach key $keys(keys) { if {![string equal $foo($key) $bar($key)]} { return 0 } } return 1 }
escargo 20 Nov 2002 - So, just to summarize: Arrays are equal iff
Is there a significant performance or space penalty for having to call lsort external to array names instead of having array names have a parameter that does the sorting internally?
See also Memory costs with Tcl for measurement of array/list element consumption in bytes.
{{ Tcl syntax help | Arts and crafts of Tcl-tk programming | Category Command (of Tcl) | Category Data Structure | ]