【发布时间】:2011-04-06 14:29:54
【问题描述】:
假设我有一个 TCL 列表:
set myList {}
lappend myList [list a b 1]
lappend myList [list c d 2]
.....
现在我想像这样修改列表:
foreach item $myList {
lappend item "new"
}
但最后我没有修改列表。为什么? item 是列表项编号上的引用吗?
【问题讨论】:
假设我有一个 TCL 列表:
set myList {}
lappend myList [list a b 1]
lappend myList [list c d 2]
.....
现在我想像这样修改列表:
foreach item $myList {
lappend item "new"
}
但最后我没有修改列表。为什么? item 是列表项编号上的引用吗?
【问题讨论】:
item 不是对列表项的引用。这是一个副本。做你想做的事,你可以这样做:
set newlist {}
foreach item $myList {
lappend item "new"
lappend newlist $item
}
set mylist $newlist
【讨论】:
要“就地”编辑列表,您可以这样做:
set idx -1
foreach item $myList {
lappend item "new"
lset myList [incr idx] $item
}
如果你有 Tcl 8.6,你也可以这样做(注意我实际上并没有使用$item;它只是方便循环):
set idx -1
foreach item $myList {
lset myList [incr idx] end+1 "new"
}
但它不适用于 8.5,其中 lset 只会替换现有项目(和子列表)。
【讨论】:
for {set i 0} {$i < [llength $myList]} {incr i} {
set item [lindex $myList $i]
lappend item new
set myList [lreplace $myList $i $i $item]
}
如果您的列表非常大,可以提高一些效率(例如K combinator)。他们只会在这里增加复杂性。
【讨论】:
foreach item $myList {
lappend item "new"
}
您在这里所做的是获取一个变量(称为项目),并将其修改为也包含“新”。基本上,您会得到类似于{a new}、{b new} 等的列表。但是你会在每次迭代结束时泄露这些变量。
你真正希望你的清单在完成后是什么样子的?
【讨论】: