удалить подсписок из списка в tcl - PullRequest
5 голосов
/ 10 октября 2011

Я хочу удалить подсписок из списка в Tcl. Я знаю, как сделать это для основного списка, используя lreplace, но я не знаю, как сделать это для подсписка. Например:

set a { 1 2  { {3 4} { 4 } } }

Теперь я хочу удалить {4} из внутреннего списка { {3 4} {4} }. Окончательный список должен быть:

a { 1 2  { {3 4} } }

Пожалуйста, предложите, как расставить точки.

Ответы [ 3 ]

2 голосов
/ 10 октября 2011

Объедините lindex, чтобы получить внутренний подсписок, lreplace, чтобы удалить элемент извлеченного внутреннего подсписка, и lset, чтобы вернуть измененный подсписок обратно.

Но, честно говоря, я чувствую, что с вашей моделью данных что-то не так.

1 голос
/ 11 октября 2011

Требуется несколько хитростей, чтобы сделать красиво:

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 голос
/ 10 октября 2011
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...