I have a nested list as follows:
set myList {
{first apples dollars}
{second bananas euros}
{third pears pesos}
}
In Tcl 8.7, I can use lsearch -index 2
(eg) if I want to find the type of fruit I'm selling in euros:
set myFruit [lindex $myList [lsearch -index 2 $myList "euros"] 1]
puts $myFruit
# returns bananas
But how do I do that in Tcl 8.4 where the -index
switch doesn't exist? Is there a shortcut, or will I have to use a foreach
?
I would like to do this with TCl's native functionality, if possible, and not via any additional packages (which I unfortunately cannot use for my particular project).
Using the wildcard option of lsearch
might be what you are looking for?
set myList {
{first apples dollars}
{second bananas euros}
{third pears pesos}
}
set myFruit [lindex $myList [lsearch $myList "*euros*"] 1]
puts $myFruit
Though the above would also match the word 'neuroscience' for example, so you could use something like the below if that's a possibility:
lsearch -regexp $myList {\yeuros\y}
If it gets more complex, like, if you want to match the entire sub-element (and therefore not want to match euros
in the element {forth kiwi "0.5 euros each"}
then instead of trying to make the search more flexible, I believe it would be much easier to use a loop:
for {set i 0} {$i < [llength $myList]} {incr i} {
if {"euros" in [split [lindex $myList $i]]} {
set myFruit [lindex $myList $i]
puts $myFruit
}
}
This is more an extension to Jerry's answer:
If going down the regexp
route, and you can guarantee that the input list of lists is regular in the sense of a sanitized Tcl-list string representation, then you can have regexp
do all the work:
lindex [regexp -all -inline {([^\s]+)\s+euros\}} $myList] 1
This also covers for the case of multiple sub-lists having euros
as elements.
foreach {_ v} [regexp -all -inline {([^\s]+)\s+euros\}} $myList] {puts $v}
According to 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"
}
The keylget command in this syntax returns 1 if found, 0 if not. The value next to bbb (2) is then placed in the variable myvar. Note that there should be no dollar sign ($) in front of somelist in the keylget command.
So for your example that would be:
set searchTerm "euros"
if {[keylget myList $searchTerm myFruit]} {
puts $myFruit
}
(Not marking this as a duplicate because 589332 didn't deal with v8.4 specifically; someone just happened to mention it in one of the answers.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.