【问题标题】:Tcl: How can I search a nested list in Tcl 8.4?Tcl:如何在 Tcl 8.4 中搜索嵌套列表?
【发布时间】:2019-03-13 18:25:27
【问题描述】:

我有一个嵌套列表如下:

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

但是在不存在 -index 开关的 Tcl 8.4 中,我该怎么做呢?有快捷方式吗,还是我必须使用foreach

如果可能的话,我想使用 TCl 的本机功能而不是通过任何其他包(很遗憾我不能将其用于我的特定项目)来做到这一点。

【问题讨论】:

  • 你到底为什么坚持使用 8.4?它是旧且不受支持的。强迫你进入那种情况的人是坏的,应该感觉不好。现在是 2019 年,而不是 2004 年!
  • 卡在 tcl 8.4 上的原因可能有很多,如果没有任何问题,许多客户会冻结更改,他们可能会要求偶尔打补丁,但 Tcl 可能不符合升级条件。

标签: list search tcl


【解决方案1】:

使用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}

如果它变得更复杂,例如,如果你想匹配整个子元素(因此不想匹配元素 {forth kiwi "0.5 euros each"} 中的 euros,那么我相信而不是试图使搜索更灵活使用循环会容易得多:

for {set i 0} {$i < [llength $myList]} {incr i} {
    if {"euros" in [split [lindex $myList $i]]} {
        set myFruit [lindex $myList $i]
        puts $myFruit
    }
}

【讨论】:

    【解决方案2】:

    这更像是对 Jerry 答案的扩展:

    如果沿着regexp 路线前进,并且您可以保证列表的输入列表在经过净化的Tcl 列表字符串表示的意义上是常规的,那么您可以让regexp 完成所有工作:

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

    这也适用于以euros 作为元素的多个子列表的情况。

     foreach {_ v}  [regexp -all -inline {([^\s]+)\s+euros\}} $myList] {puts $v}
    

    【讨论】:

      【解决方案3】:

      根据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 命令中的 somelist 前面不应有美元符号 ($)。

      所以你的例子是:

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

      (不将此标记为重复,因为 589332 没有专门处理 v8.4;有人恰好在其中一个答案中提到它。)

      【讨论】:

      • 如何在不使用包的情况下实现最初的目标(除了卡在 8.4 之外,这是我目前的另一个限制 - 没有加载包的能力/权限)
      • 在这种情况下,我认为您可能会被foreach 卡住。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 1970-01-01
      • 2016-06-13
      相关资源
      最近更新 更多