Tcl: Как я могу найти вложенный список в Tcl 8.4? - PullRequest
0 голосов
/ 13 марта 2019

У меня есть следующий вложенный список:

set myList {
   {first apples dollars}
   {second bananas euros}
   {third pears pesos}
}

В Tcl 8.7 я могу использовать lsearch -index 2 (например), если я хочу найти тип фруктов, которые я продаю в евро:

set myFruit [lindex $myList [lsearch -index 2 $myList "euros"] 1]
puts $myFruit    
# returns bananas

Но как мне это сделать в Tcl 8.4, где переключатель -index не существует? Есть ли ярлык или мне придется использовать foreach?

Я хотел бы сделать это с нативной функциональностью TCl, если это возможно, а не с помощью каких-либо дополнительных пакетов (которые, к сожалению, я не могу использовать для моего конкретного проекта).

Ответы [ 3 ]

1 голос
/ 14 марта 2019

Возможно, вам понадобится использовать подстановочный знак lsearch?

set myList {
   {first apples dollars}
   {second bananas euros}
   {third pears pesos}
}

set myFruit [lindex $myList [lsearch $myList "*euros*"] 1]
puts $myFruit

Хотя приведенное выше также будет соответствовать слову "нейробиология", например, вы можете использовать что-то вроде следующегоесли это возможно:

lsearch -regexp $myList {\yeuros\y}

Если это становится более сложным, например, если вы хотите сопоставить весь подэлемент (и, следовательно, не хотите сопоставлять euros в элементе {forth kiwi "0.5 euros each"} тогда вместо того, чтобы пытаться сделать поиск более гибким, я считаю, что было бы намного проще использовать цикл:

for {set i 0} {$i < [llength $myList]} {incr i} {
    if {"euros" in [split [lindex $myList $i]]} {
        set myFruit [lindex $myList $i]
        puts $myFruit
    }
}
1 голос
/ 14 марта 2019

Это больше расширение ответа Джерри:

Если идти по маршруту regexp, и вы можете гарантировать, что входной список списков является регулярным в смысле очищенного представления строки Tcl-list, тогда вы можете сделать regexp всю работу:

 lindex [regexp -all -inline {([^\s]+)\s+euros\}} $myList] 1

Это также относится к случаю нескольких подсписков, имеющих euros в качестве элементов.

 foreach {_ v}  [regexp -all -inline {([^\s]+)\s+euros\}} $myList] {puts $v}
0 голосов
/ 13 марта 2019

Согласно 589332 :

package require Tclx

set somelist {{aaa 1} {bbb 2} {ccc 1}}
set searchTerm "bbb"
if {[keylget somelist $searchTerm myvar]} {
    puts "Found instance of $searchTerm, value is: $myvar"
}

Команда keylget в этом синтаксисе возвращает 1, если найдено, 0, если нет.Значение рядом с bbb ​​(2) затем помещается в переменную myvar.Обратите внимание, что в команде keylget не должно быть знака доллара ($) перед каким-либо списком.

Так что для вашего примера это будет:

set searchTerm "euros"
if {[keylget myList $searchTerm myFruit]} {
    puts $myFruit
}

(Не отмечать этокак дубликат, потому что 589332 конкретно не имел дело с v8.4; кто-то случайно упомянул об этом в одном из ответов.)

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