如何在TCL中创建并迭代散列?
如何在TCL中创建并迭代散列 如果我有以下数据:如何在TCL中创建并迭代散列?,tcl,Tcl,如何在TCL中创建并迭代散列 如果我有以下数据: foo = { a => { aa => { aa1 aa2 aa3 } ab => { ab1 ab2 ab3 } ac => { ac1 ac2 ac3 } } b => { ba => { ba1 ba2 ba3 } bb => { bb1 bb2 bb3 } bc => {
foo = {
a => {
aa => { aa1 aa2 aa3 }
ab => { ab1 ab2 ab3 }
ac => { ac1 ac2 ac3 }
}
b => {
ba => { ba1 ba2 ba3 }
bb => { bb1 bb2 bb3 }
bc => { bc1 bc2 bc3 }
}
c => {
ca => { ca1 ca2 ca3 }
cb => { cb1 cb2 cb3 }
cc => { cc1 cc2 cc3 }
}
}
如何通过一次插入一个叶节点数据项来创建这样的散列。比如:
lappend foo(a)(ab)“ab1”
那么如何迭代所有数据元素?比如:
foreach key in foo {
foreach sub_key in foo($key) {
foreach elem in foo($key)($sub_key) {
puts "foo\($key\)\($sub_key\) is $elem"
}
}
}
编辑:
不幸的是,我无法访问较新的“dict”结构。假设您使用的是Tcl 8.5+,那么字典就是最好的选择: 定义字典只需执行以下操作:
set foo {
a {
aa { aa1 aa2 aa3 }
ab { ab1 ab2 ab3 }
ac { ac1 ac2 ac3 }
}
b {
ba { ba1 ba2 ba3 }
bb { bb1 bb2 bb3 }
bc { bc1 bc2 bc3 }
}
c {
ca { ca1 ca2 ca3 }
cb { cb1 cb2 cb3 }
cc { cc1 cc2 cc3 }
}
}
或以编程方式对其进行定义:
set foo [dict create]
foreach first {a b c} {
dict update foo $first subdict {
foreach second {a b c} {
foreach third {1 2 3} {
dict lappend subdict "$first$second" "$first$second$third"
}
}
}
}
并将其输出:
dict for {key1 subdict} $foo {
dict for {key2 list} $subdict {
foreach elem $list {
puts "$key1\t$key2\t$elem"
}
}
}
编辑:将阵列解决方案(非dict)移动到单独的答案。如果您不使用Tcl 8.5,则可以使用阵列。请注意,数组是一维的,但键是可用于伪造多维性的任意字符串:
array set foo {}
foreach first {a b c} {
foreach second {a b c} {
foreach third {1 2 3} {
lappend foo($first,$first$second) "$first$second$third"
}
}
}
parray data
并输出它--注意:数组键与字典键不同,是无序的:
foreach key [array names foo] {
foreach elem $foo($key) {
puts "$key\t$elem"
}
}
如果给您提供了键(例如“b”和“bc”),您可以得到相应的值:
set key1 b
set key2 bc
foreach elem $foo($key1,$key2) {puts $elem}
如果您只想在不使用dict命令的情况下迭代dict(这只是一个键值对列表),那么您可以简单地使用foreach的强大功能:
set foo {
a {
aa { aa1 aa2 aa3 }
ab { ab1 ab2 ab3 }
ac { ac1 ac2 ac3 }
}
b {
ba { ba1 ba2 ba3 }
bb { bb1 bb2 bb3 }
bc { bc1 bc2 bc3 }
}
c {
ca { ca1 ca2 ca3 }
cb { cb1 cb2 cb3 }
cc { cc1 cc2 cc3 }
}
}
foreach {key value} $foo {
foreach {sub_key sub_value} $value {
foreach elem $sub_value {
puts "foo\($key\)\($sub_key\) is $elem"
}
}
}
另一方面,如果没有dict命令,一次插入一个元素是痛苦的:
set foo {}
lappend foo a {}
set a_index [lsearch $foo a]
set a_value_index [expr {$a_index+1}]
set a_value [lindex $foo $a_value_index]
lappend a_value aa {}
lset foo $a_value_index $a_value
# it is now too painful for me to continue :-(
幸运的是,您可以使用dict命令的纯tcl实现:如果您没有tcl 8.5字典的奢华,请使用键控列表命令来完成任务。你可以用谷歌搜索其中一个术语:keylget,keylset
package require Tclx
# Create the nested structure
catch {unset foo}
foreach key1 {a b c} {
foreach key2 {a b c} {
catch {unset element}
foreach key3 {1 2 3} {
lappend element "$key1$key2$key3"
}
keylset foo $key1.$key1$key2 $element
}
}
# Access the nested structure
foreach key1 {a b c} {
foreach key2 {a b c} {
set elementList [keylget foo $key1.$key1$key2]
foreach element $elementList {
puts "foo\\$key1\\$key1$key2\\$key3 = $element"
}
}
}
#
# Access examples
#
# Access a block of data
puts "foo\\a = [keylget foo a]"
# Access a nested block of data
puts "foo\\b\\ba = [keylget foo b.ba]"
# Access an individual element, remember that Tcl's list index is 0 based
puts "foo\\c\\cb\\1 = [lindex [keylget foo c.cb] 0]"
我无法访问“dict”结构。。谢谢你的回答。我将我的答案分成两半,以突出显示非dict解决方案。