How can I make sure TCL doesn't mess up the order of the elements in the array?

The problem is that the order in which I “insert” elements into the array changes during the execution of the script.

Here is a quick reproduction of the problem:

#!/bin/bash
# : \
exec /home/binops/afse/eer/eer_SPI-7.3.1/tclsh "$0" "$@"

proc myProc { theArray } {
  upvar $theArray theArrayInside
  parray theArrayInside
  puts "------"
  foreach { key value } [array get theArrayInside] {
    puts "$key => $value"
  }
}

# MAIN
set myArray(AQHI) AQHI
set myArray(O3) 1
set myArray(NO2) 2
set myArray(PM2.5) 3

parray myArray
puts "------"
myProc myArray

Output:

myArray(AQHI)  = AQHI
myArray(NO2)   = 2
myArray(O3)    = 1
myArray(PM2.5) = 3
------
theArrayInside(AQHI)  = AQHI
theArrayInside(NO2)   = 2
theArrayInside(O3)    = 1
theArrayInside(PM2.5) = 3
------
PM2.5 => 3
O3 => 1
NO2 => 2
AQHI => AQHI

Note. I did not use shared keys like A, B, C and common values ​​like 1, 2, 3, as you might expect. This is because the order is not corrupted by these generalized keys / values. Perhaps this will help identify the problem.

Also note that the initial order (AQHI, O3, NO2, PM2.5) is lost even on the first call parray(now the order of AQHI, NO2, O3, PM2.5, sorted alphabetically?). Then it changes again when called array get ...(reverse?)

, : , ?

+3
2

Tcl , , . , , , :

proc array_add {ary_name key value} {
    upvar 1 $ary_name ary
    set ary($key) $value
    lappend ary() $key
}

proc array_foreach {var_name ary_name script} {
    upvar 1 $var_name var
    upvar 1 $ary_name ary
    foreach var $ary() {
        uplevel 1 $script
    }
}

array_add a foo bar
array_add a baz qux
array_add a abc def
array_add a ghi jkl

array_foreach key a {puts "$key -> $a($key)"}
# foo -> bar
# baz -> qux
# abc -> def
# ghi -> jkl

array names a
# ghi {} foo baz abc

array get a
# ghi jkl {} {foo baz abc ghi} foo bar baz qux abc def

parray a
# a()    = foo baz abc ghi
# a(abc) = def
# a(baz) = qux
# a(foo) = bar
# a(ghi) = jkl
0

Tcl , C, . Tcl ( ), HashMap Java, .

( , ).

8.5 , dict, , - . backport Tcl 8.5, , ( ).

8.5 dicts /, , lsearch, .

> set mylist {{key1 value1} {key2 value2} {key3 value3}}
> lsearch -index 0 $mylist key2
0
> lindex $mylist [list [lsearch -index 0 $mylist key2] 1]
> value2
> proc kv_lookup {dictList key} {
      set index [lsearch -index 0 $dictList $key]
      if {$index < 0} {
          error "Key '$key' not found in list $dictList"
      }
      return [lindex $dictList [list $index 1]]
  }
> kv_lookup $mylist key2
value2

man 8.4

Tcl. , , .

"" , java HashMap () LinkedHashMap ().

+6

All Articles