удалить подсписок из списка в tcl

#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. Я думаю, его проблема заключалась бы в том, чтобы знать путь … и поэтому ему все равно нужно было зациклить свой список, чтобы увидеть, какой элемент его списка / подсписка является единственным значением (его критерием).