Список TCL и проблема foreach - PullRequest
       24

Список TCL и проблема foreach

1 голос
/ 06 апреля 2011

Скажем, у меня есть список TCL:

set myList {}
lappend myList [list a b 1]
lappend myList [list c d 2]
.....

Теперь я хочу изменить список следующим образом:

foreach item $myList {
lappend item "new"
}

Но в конце я не изменил список.Зачем?элемент является ссылкой на элемент списка нет?

Ответы [ 4 ]

7 голосов
/ 06 апреля 2011

item - это , а не ссылка на элемент списка. Это копия . Чтобы сделать то, что вы хотите, вы можете сделать это:

set newlist {}
foreach item $myList {
  lappend item "new"
  lappend newlist $item
}
set mylist $newlist
2 голосов
/ 07 апреля 2011

Чтобы редактировать список «на месте», вы можете сделать это:

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 заменит только существующие элементы (и подсписки).

0 голосов
/ 06 апреля 2011
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 комбинатор ).Они просто добавили бы сюда сложность.

0 голосов
/ 06 апреля 2011
foreach item $myList {
    lappend item "new"
}

То, что вы здесь делаете, - это получение переменной (называемой item) и изменение ее так, чтобы она также содержала «new».в основном вы получаете списки, которые выглядят как {a new}, {b new} и так далее.Но вы пропускаете эти переменные в конце каждой итерации.

Как вы действительно хотите, чтобы ваш список выглядел, когда вы закончите?

...