在TCL中使用foreach
循环遍历列表时,需要具有当前对象的索引的运行编号。我以前做过的一种方法是保持一个额外的计数器变量。
set ct 0
foreach x $list {
puts "Items is $x index is $ct"
incr ct
}
可以使用lsreach来检索索引但这是计算密集型的,并且可能会出现双重问题。
想知道在循环过程中是否有流线型的光滑外观来维护索引信息。
伪代码:
foreach x $list {
puts "Items is $x index is [foreach_index $x]"
}
感谢您的反馈。
更新:
使用提供的答案进行运行时测试:
使用100k随机字符串80char long循环遍历列表。 循环过程最快,但难以阅读。
答案 0 :(得分:2)
虽然其他语言的控制结构定义是法律,但在Tcl中它们更像是一套指导原则。
proc foreachWithIndex {indexVar args} {
upvar 1 $indexVar var
set var 0
uplevel 1 [list foreach {*}[lrange $args 0 end-1] "[lindex $args end];incr $indexVar"]
}
foreachWithIndex x v {a b c} {puts "$x: $v"}
但我建议改用for
。激进的语言修改很有趣,偶尔也很有用,但是如果我对每一个这样聪明的构造都有一个帝国的功劳,我最后扔掉了,我可以建造我自己的死星,并且仍然有钱在排气口上放置光栅。
答案 1 :(得分:0)
将incr
与计数器一起使用的方法可以正常工作。这也有效:
for { set i 0 } { $i < [llength $list] } { incr i } {
set x [lindex $list $i]
puts "Items is $x index is $i"
}
这样做的另一个好处是您可以在迭代时修改列表。假设您要从列表中删除值为“bad”的所有项目。
set values { 1 2 3 bad 4 bad bad 5 }
for { set i 0 } { $i < [llength $values] } { incr i } {
if { [lindex $values $i] eq "bad" } {
set values [lreplace $values $i $i]
incr i -1
}
}
puts $values