问题是,我在数组中“插入”元素的顺序在整个脚本执行过程中都会发生变化。
以下是问题的快速再现:
#!/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输出为:
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请注意,我没有使用像A,B,C这样的泛型键和像1,2,3这样的泛型值,这可能是您所期望的。这是因为顺序不会与这些泛型键/值打乱。也许这可以帮助识别问题。
还要注意,即使在第一次调用parray时,初始顺序(AQHI、O3、NO2、PM2.5)也会丢失(顺序现在是AQHI、NO2、O3、PM2.5;按字母顺序排序?)。然后在调用array get ...时再次更改它(inversed?)
所以不管怎样,问题是:我如何确保保持最初的顺序?
发布于 2011-06-02 18:31:32
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发布于 2011-06-02 07:10:20
将Tcl数组等同于C语言中的Tcl数组是错误的,在C语言中,Tcl数组是一个元素列表。相反,Tcl数组是映射(从键到值),就像Java语言中的HashMap一样,元素的顺序不会被保留。
使用列表可能会更好(如果您只需要按顺序存储多个项目)。
如果你使用的是8.5或更高版本,如果你实际上有一个键到值的映射,那么就需要一个dict,因为字典是保持顺序的映射。对于8.5之前的Tcl版本,有一些dict backport,但我不确定它们是否保持了秩序(而且速度更慢)。
如果不能使用8.5字典并且需要键/值对,一种选择是使用键值对列表,然后使用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
value28.4的手册页是here
你可能还想看看Tcl在keyed lists上的这个页面。它实现了我上面提到的内容,外加一些其他有用的命令。
有关有序“映射”和无序“映射”之间的区别的示例,您可以查看两个java类HashMap (无序)和LinkedHashMap (有序)。
https://stackoverflow.com/questions/6208727
复制相似问题