如何将switch中的变量与列表内容进行匹配?

时间:2011-12-21 12:33:29

标签: list tcl switch-statement

我怀疑在tcl中使用switch。主要是,我想知道是否有可能做出类似的事情:

switch myvar {
    list1 {
        puts "myvar matches contents of list1"; }
    list2 {
        puts "myvar matches contents of list2"; }
    default {
        puts "myvar doesn't match any content of any list"; }
}

在这里,list1和list2可以是包含不同文件名称的列表或字符串数​​组。

如果不进行非常详细的正则表达式搜索,这是否可行?

谢谢!

2 个答案:

答案 0 :(得分:6)

你可以轻松地将它重写为if elseif else构造,就像Brian Fenton已经说过的那样(并用'in'运算符简化它。

if {$myvar in $list1} {
    puts "myvar matches content of list"
} elseif {$myvar in $list2} {
    puts "myvar matches content of list2"
} elseif {
    puts "myvar doesn't match any content of any list"
}

你当然可以把代码包起来并编写自己的开关版本来做你想要的,毕竟这是Tcl ......

proc listswitch {item conditions} {
     if {[llength $conditions] % 2} {
         return -code error "Conditions must be pairs"
     }
     set code ""
     foreach {cond block} $conditions {
        if {$cond eq "default"} { 
          set code $block
          break 
        } elseif {$item in $cond} {
          set code $block
          break
        }
     }
     if {$code ne ""} {
         uplevel 1 $code
     }
}


listswitch 10 {
   {10 20 30 50} {
       puts "Match in list 1" }
   {50 20 90 11} { 
       puts "Match in list 2"
    }
    default {
       puts "No match"
    }
}

如果你想要字面上匹配文件名,或者你感兴趣的是什么样的平等,你需要担心一点。有一些微妙的东西,如不区分大小写的文件系统,不同的目录分隔符,绝对与相对,甚至文件系统编码等可能会改变结果的东西。

答案 1 :(得分:1)

好问题杰森。起初,我认为你想要一种方法来比较两个列表的内容。但我想你想检查字符串是否是列表的成员。我没有看到使用开关做任何简单的方法,所以我要做的就是使用 lsearch

if {[lsearch $list1 $myvar ] != -1} {
  puts "myvar matches contents of list1"; }
} elseif {[lsearch $list2 $myvar ] != -1} {
  puts "myvar matches contents of list2"; }
} else
  puts "myvar doesn't match any content of any list"; }
}