迭代多个TCL数组

  • 本文关键字:数组 TCL 迭代 tcl
  • 更新时间 :
  • 英文 :


我想循环遍历一个或多个TCL数组,例如打印一个特定的值。

最好用代码来描述:

# Init
array unset one; array set one {param 1}
array unset two; array set two {param 2}
#Works fine
puts "one=$one(param)"
puts "two=$two(param)"
#Nope
foreach ar "one two" {puts ${$ar(param)}}
#Works, but makes a copy.
foreach tmp "one two" {
  array unset ar
  array set ar [array get $tmp]
  puts "$tmp=$ar(param)"
}

这个"工作"的情况会产生一个副本(我想这没什么大不了的),但它看起来不正确。我更喜欢有一些更干净的东西,比如"Nope"情况(但它可以工作:)。

我同意这很丑。做这类事情的最好方法是使用局部变量别名

foreach arrayName {one two} {
    upvar 0 $arrayName ar
    puts "$arrayName=$ar(param)"
}

建议最好在过程中完成,因为您无法真正撤消变量混叠。这可以使upvar的使用更加常规。

proc printEntry {entry args} {
    foreach arrayName $args {
        # Use [upvar 1] because we want the caller's name
        upvar 1 $arrayName ar
        puts "$arrayName=$ar($entry)"
    }
}
printEntry param one two

(如果您使用upvar,请始终使用级别参数-上面的01 -以避免一些丑陋的错误解析问题)

如果您真的想让Nope情况起作用,另一种解决方案是记住$x只是[set x]set的简写,作为一个合适的命令,CC_6与tcl语法的其余部分比$更好。

因此,将双upvar 00重新表述为set,我们得到了这个工作代码:

foreach ar "one two" {puts [set [set ar](param)]}

第一轮替换,[set ar]仅仅用值"one"或"two"替换ar。在这种情况下,set相对于$的优势在于,它让程序员能够控制在哪里停止替换。我们可以选择[set ar(param)]$ar(param)一样也可以选择[set ar](param),这是我们想要的

或者,您可以更改您的数据结构:

# Init
array set a {
    "one,param" 1
    "two,param" 2
}
puts "one=$a(one,param)"
puts "two=$a(two,param)"
foreach key {one two} {puts $a($key,param)}

最新更新