Вы фактически сравниваете только список x
со списком x
, и фактический вывод из вашего кода выше (при условии, что список l2
изначально пуст) на самом деле:
1 2 3 4 5 8 9
Вы можетеспросите:
Почему он сравнивает список x
со списком x
?
Ваш внутренний цикл начинается с индекса 1 (set i 1
), который является спискомx
in l1
.
Вы могли бы дополнительно спросить:
Почему другие списки не сравниваются?
После добавлениячто-то в l2
, lindex $l2 $j
для следующего списка никогда не будет пустым, поэтому внутренний цикл оборвется.
Итак, как это сделать?
Я бы, наверное,используйте что-то вроде этого:
set w {1 2 3 4 5 6 7}
set x {1 2 3 4 5 8 9}
set y {1 2 3 4 0 9 1}
set z {1 2 3 4 5 6 7}
set l1 [list $w $x $y $z]
set l2 [list]
set num [llength $x]
for {set i 0} {$i < $num} {incr i} {
# This variable will tell us how many matched. 0 indicating none.
set same 0
for {set j 0} {$j < [llength $l1]} {incr j} {
# lindex accepts multiple indices, see the manual
# using x as reference, if the current list's ith element is the same as x's ith element...
if {[lindex $l1 $j $i] == [lindex $x $i]} {
incr same
}
}
# if same reached 4, means 4 matched
if {$same == 4} {
lappend l2 [lindex $x $i]
}
}
Результат:
1 2 3 4
Вы можете сделать разрыв внутреннего цикла, если элементы не совпадают, поэтому он не будет повторяться без необходимости.
Или вместо подсчета количества совпадений вы можете проверить, не сломался ли внутренний цикл, например:
for {set i 0} {$i < $num} {incr i} {
set broke 0
for {set j 0} {$j < [llength $l1]} {incr j} {
if {[lindex $l1 $j $i] != [lindex $x $i]} {
set broke 1
break
}
}
# if it did not break, then we know all matched
if {$broke == 0} {
lappend l2 [lindex $x $i]
}
}