#tcl
#tcl
Вопрос:
Я хочу удалить подсписок из списка в Tcl. Я знаю, как это сделать для основного списка lreplace
, но я не знаю, как это сделать для подсписка. Например:
set a { 1 2 { {3 4} { 4 } } }
Теперь я хочу удалить {4}
из внутреннего списка { {3 4} {4} }
.
Окончательный список должен быть:
a { 1 2 { {3 4} } }
Пожалуйста, предложите, как расставить его точки.
Комментарии:
1. чего нам не хватает, так это критериев, необходимых для выбора элемента для удаления, т.Е. Всегда ли это 2-й подсписок в 3-м подсписке или что-то еще?
2. кроме того, lreplace фактически не создает новый список, он не выполняет замену на месте
3. критерием является наличие менее двух элементов во внутреннем подсписке списка { {3 4} {4} }, уберите его. как и в {3 4}, у нас есть элементы, но в {4} есть только один элемент, поэтому мне нужно удалить {4}.
Ответ №1:
Объедините lindex
, чтобы получить внутренний подсписок, lreplace
удалить элемент извлеченного внутреннего подсписка и lset
вернуть измененный подсписок на место.
Но, честно говоря, у меня такое чувство, что с вашей моделью данных что-то не так.
Ответ №2:
proc retlist {a} {
set nl ""
foreach i $a {
if {[llength $i] > 1} {
set nl2 ""
foreach i2 $i {
if {[llength $i2] > 1} { lappend nl2 $i2 }
}
lappend nl $nl2
} else {
lappend nl $i
}
}
return $nl
}
Если вам нужна переменная глубина, вы потерялись с этим кодом. Для этого вам нужна рекурсия.
% set a {1 2 {{3 4} {5}}}
1 2 {{3 4} {5}}
% retlist $a
1 2 {{3 4}}
Поскольку внешний список никогда не отображается в tclsh.
Ответ №3:
Для этого требуется несколько трюков:
proc lremove {theList args} {
# Special case for no arguments
if {[llength $args] == 0} {
return {}
}
# General case
set path [lrange $args 0 end-1]
set idx [lindex $args end]
lset theList $path [lreplace [lindex $theList $path] $idx $idx]
}
set a [lremove $a 2 1]
Это работает, потому что оба lset
и lindex
могут принимать пути, и они делают разумные вещи и с пустым путем.
Комментарии:
1. Я думаю, его проблема заключалась бы в том, чтобы знать путь … и поэтому ему все равно нужно было зациклить свой список, чтобы увидеть, какой элемент его списка / подсписка является единственным значением (его критерием).