Tcl lsearch in list list

Tcl has a list list.

set somelist {{aaa 1} {bbb 2} {ccc 1}}

How do I search for a list item, which is the first item "bbb"?

I tried this way, but it does not work.

lsearch $somelist "{bbb *}"

Thank.

+5
source share
5 answers

Use -index , it is designed specifically for this case. As Ramanman points out, when you have a list, use list procedures. Have you ever wondered what will happen if you have several matches?

In your case, I would just do this:

% lsearch -index 0 -all -inline $somelist bbb
{bbb 2}
% lsearch -index 0 -all $somelist "bbb"
1
% lsearch -index 0 -all $somelist "ccc"
2

-index 0, , . -all . -inline, , , , .

+7

, -index :

set pos [lsearch -index 0 -exact $somelist "bbb"]

-index 0 lsearch ( lindex $item 0) (-exact ). - ..

( NB: , lsearch , . , , .)


EDIT:
Tcl, -index. :

proc findElement {lst idx value} {
    set i 0
    foreach sublist $lst {
        if {[string equal [lindex $sublist $idx] $value]} {
            return $i
        }
        incr i
    }
    return -1
}
set pos [findElement $somelist 0 "bbb"]

( glob . , , .)

+5

Tcl 8.5, Tcl 8.4:

set somelist {{aaa 1} {bbb 2} {ccc 1}}
lsearch -index 0 $somelist bbb; # Returns either the index if found, or -1 if not

-index , : 0 aaa, bbb,... 1 1, 2, 1...

Tcl 8.4 keylget Tclx:

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 ($).

Update

, -index , :

package require Tcl 8.5 

# For each sub-list:
# - index 0 = the user name
# - index 1 = a list of {home value}
# - index 2 = a list of {id value}
# - index 3 = a list of {shell value}
set users {
    {john {home /users/john} {id 501} {shell bash}}
    {alex {home /users/alex} {id 502} {shell csh}}
    {neil {home /users/neil} {id 503} {shell zsh}}
}   

# Search for user name == neil
set term neil
puts "Search for name=$term returns: [lsearch -index 0 $users $term]"; # 2

# Search for user with id = 502. That means we first looks at index
# 2 for {id value}, then index 1 for the value
set term 502
puts "Search for id=$term returns: [lsearch -index {2 1} $users $term]"; # 1

# Search for shell == sh (should return -1, not found)
set term sh
puts "Search for shell=$term returns: [lsearch -index {3 1} $users $term]"; # -1
+4

"-index" [lsearch].

+2

, , glob:

lsearch -glob $somelist "{bbb *}"

, bbb, :

foreach sublist $somelist {   
  foreach {name value} $sublist {
    if {[string eq $name "bbb"]} {
      #do interesting stuff here
    }
  }
}

The details of this, of course, will depend on the details of your list of lists (if you actually only have two elements of your nested list or if it can be more deeply nested.

+1
source

All Articles