TCL удаляет элемент из списка

#list #element #tcl

#Список #элемент #tcl

Вопрос:

Как удалить элемент из списка TCL, скажем:

  1. который имеет индекс = 4
  2. который имеет значение = «aa»

Я погуглил и пока не нашел никакой встроенной функции.

Ответ №1:

 set mylist {a b c}
puts $mylist
a b c
  

Удалить по индексу

 set mylist [lreplace $mylist 2 2]
puts $mylist 
a b
  

Удалить по значению

 set idx [lsearch $mylist "b"]
set mylist [lreplace $mylist $idx $idx]
puts $mylist
a
  

Комментарии:

1. Это здорово, но мой список состоит из подсписков, и я хочу проверять в каждом подсписке, если значение во втором индексе равно 0 (например), я хочу удалить этот подсписк. Как я должен это сделать. P.S. Проблема в том, что [lindex $ list] возвращает значение, а не ссылку

2. @Narek Тогда, пожалуйста, обновите свой вопрос, чтобы он был таким, какой вы хотите, b / c drysdam ответил на то, что вы спросили.

3. Пожалуйста, измените [lreplace $idx $idx] на [lreplace $mylist $idx $idx].

4. Одна крошечная вещь; разве результат в последнем элементе не должен быть a c , а не просто a ?

Ответ №2:

Другой способ удалить элемент — это отфильтровать его. Этот метод Tcl 8.5 отличается от метода lsearch amp; lreplace , упомянутого в другом месте, тем, что он удаляет все заданные элементы из списка.

 set stripped [lsearch -inline -all -not -exact $inputList $elemToRemove]
  

Чего он не делает, так это поиска по вложенным спискам. Это следствие того, что Tcl не прилагает усилий для слишком глубокого понимания ваших структур данных. (Однако вы можете указать ему поиск, сравнив определенные элементы подсписков, с помощью -index опции.)

Ответ №3:

Допустим, вы хотите заменить элемент «b»:

 % set L {a b c d}
a b c d
  

Вы заменяете первый элемент 1 и последний элемент 1 ничем:

 % lreplace $L 1 1
a c d
  

Ответ №4:

regsub также может подойти для удаления значения из списка.

 set mylist {a b c}
puts $mylist
  a b c

regsub b $mylist "" mylist

puts $mylist
  a  c
llength $mylist
  2
  

Ответ №5:

Просто завершаю то, что сделали другие

 proc _lremove {listName val {byval false}} {
    upvar $listName list

    if {$byval} {
        set list [lsearch -all -inline -not $list $val]
    } else {
        set list [lreplace $list $val $val]
    }

    return $list
}
  

Затем вызовите с

 Inline edit, list lappend
    set output [list 1 2 3 20]
    _lremove output 0
    echo $output
    >> 2 3 20

Set output like lreplace/lsearch
    set output [list 1 2 3 20]
    echo [_lremove output 0]
    >> 2 3 20

Remove by value
    set output [list 1 2 3 20]
    echo [_lremove output 3 true]
    >> 1 2 20

Remove by value with wildcar
    set output [list 1 2 3 20]
    echo [_lremove output "2*" true]
    >> 1 3
  

Ответ №6:

Вы также можете попробовать вот так :

 set i 0
set myl [list a b c d e f]

foreach el $myl {
   if {$el in {a b e f}} {
      set myl [lreplace $myl $i $i]
   } else {
      incr i
   }
}
set myl
  

Ответ №7:

Есть 2 простых способа.

 # index
set mylist "a c b"
set mylist [lreplace $mylist 2 2]
puts $mylist 
a b
    
# value
set idx [lsearch $mylist "b"]
set mylist [lreplace $mylist $idx $idx]
puts $mylist
a