TCL foreach跟踪索引

时间:2018-03-09 22:18:05

标签: foreach tcl

在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]"
}

感谢您的反馈。

更新:

使用提供的答案进行运行时测试:

  1. Peter Lewerin:每次迭代86098.8微秒
  2. Gert:每次迭代91057.4微秒
  3. David B:每次迭代115860.0微秒
  4. 使用100k随机字符串80char long循环遍历列表。 循环过程最快,但难以阅读。

2 个答案:

答案 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