Tcl中有一个列表清单。
set somelist {{aaa 1} {bbb 2} {ccc 1}}
如何搜索列表的元素,第一项是“bbb”?
我试过这种方式,但它不起作用。
lsearch $somelist "{bbb *}"
感谢。
答案 0 :(得分:8)
使用 -index ,它就是针对这种情况而设计的。正如拉曼曼指出的,当你有一个列表时,使用列表程序。你有没有想过如果你有多场比赛会发生什么?
在你的情况下,我会这样做:
% lsearch -index 0 -all -inline $somelist bbb
{bbb 2}
% lsearch -index 0 -all $somelist "bbb"
1
% lsearch -index 0 -all $somelist "ccc"
2
使用0的 -index 指定您对外部列表的第一个索引感兴趣。 -all 会返回所有结果。如果你只想要匹配的list元素的值,你可以使用 -inline ,如果你只想要匹配元素的索引,则省略它。
答案 1 :(得分:5)
如果您正在搜索每个列表成员的第一个子列表,-index
选项适合您:
set pos [lsearch -index 0 -exact $somelist "bbb"]
在进行任何其他比较操作之前,-index 0
选项告诉lsearch
比较引擎获取每个项目的第一个元素(即,非常像lindex $item 0
){{1}我的例子中的比较)。您甚至可以提供索引列表以深入查看特定的子子列表等。
( NB: 就是正式无法知道你什么时候离开。)
编辑:
如果您使用旧版本的Tcl,则可能没有-exact
选项。在这种情况下,您使用手动迭代:
lsearch
(我不喜欢在这种情况下使用glob匹配。当你在寻找一个不是列表中第一个或最后一个元素的元素时,它也不能很好地工作。)
答案 2 :(得分: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 ...
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命令中的某个列表前面不应有美元符号($)。
实际上,-index标志允许搜索任意深度,如下代码所示:
package require Tcl 8.5
# For each sub-list:
# - index 0 = the user's 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
答案 3 :(得分:2)
使用[lsearch]的“-index”选项。
答案 4 :(得分:1)
如果你想按照你想要的方式搜索它,你可以使用glob选项:
lsearch -glob $somelist "{bbb *}"
如果您真的是列表列表,并且您正在寻找将第一个子列表与bbb的第一个元素匹配,您也可以这样做:
foreach sublist $somelist {
foreach {name value} $sublist {
if {[string eq $name "bbb"]} {
#do interesting stuff here
}
}
}
其中的详细信息当然取决于列表列表的详细信息(如果实际上只有嵌套列表的两个元素,或者它可能更深层嵌套。