使用 Tcl 使用 Tcl 中的模式从现有列表创建过滤列表

Using Tcl to create a filtered list from an existing list using a pattern in Tcl

我的目标是获取现有列表,然后根据特定模式创建过滤器列表。我不想使用 for 循环或 while 循环。

我想要的例子

set existing_list [list "color_blue12312" "color_blue32311" "color_green123j11" "color_green234321" "color_purple213123" "color_purple234234234"]

set purple_list [lsearch existing_list color_purple*]
puts $purple_list 

这应该在终端中打印:

color_purple213123 color_purple234234234

您正在寻找 -all(Returns 所有匹配)和 -inline(Returns 匹配的元素,而不是索引)选项 lsearch:

set existing_list {color_blue12312 color_blue32311 color_green123j11
    color_green234321 color_purple213123 color_purple234234234}
set purple_list [lsearch -all -inline $existing_list color_purple*]
puts $purple_list

有两种方法可以进行这种过滤。第一,当你使用字符串匹配模式(相等、通配、正则表达式)时是 lsearch -all -inline;肖恩的回答涵盖了这一点(我 绝对 赞同这一点!)。另一种方法在您需要任何其他过滤规则时至关重要,它是使用 lmap 并在您希望值 被传递时使用 continue .

set purple_list [lmap value $existing_list {
    if {[string match color_purple* $value]} {
        # the result of the 'if' is the contents of 'value'
        string cat $value
    } else {
        continue
    }
}]

这是可行的,因为 lmap 实际上只是一个 foreach,它在脚本正常 (TCL_OK) 完成时将结果收集到列表中;特殊完成(例如 continue 使用)不会被收集。


在你问之前,是的,你可以在一次扫描中进行过滤和映射。并使用多个输入列表和多个变量来每步消耗多个元素。你为什么不呢?