Tcl:测试嵌套列表

Tcl: test for nested list

如何有效地测试 Tcl 列表是否嵌套(即包含列表作为元素)?

基于https://wiki.tcl-lang.org/page/Depth+of+a+list我构建了以下过程:

proc isNestedList {l} {
    return [expr ![string equal $l [concat {*}$l]]]
}

这给出了所需的行为(除了 {A} 的情况,据我所知通常不能以不同的方式处理,参见 ):

% isNestedList A
0
% isNestedList {A}
0
% isNestedList {{A}}
1
% isNestedList {A B}
0
% isNestedList {{A B}}
1
% isNestedList {A {B C}}
1

然而,对于非嵌套的长列表,isNestedList 很慢,可能是由于从列表到字符串的转换。我尝试了一个不同的版本,我将 $l[concat {*}$l]::struct::list equal (https://tools.ietf.org/doc/tcllib/html/struct_list.html) 进行比较以避免这种转换,但那更慢。

非常感谢您的帮助!

为避免您提到的速度变慢,您需要坚持使用列表操作,而不是字符串操作。这是一种方法:

proc isNestedList l {
    return [llength [lmap a $l {expr {[llength $a] > 1 ? 1 : [continue]}}]]
}

这使用 lmap 将列表过滤为仅那些本身可以被视为包含多个元素的列表的元素,然后检查结果列表是否为 non-empty.

我意识到我之前的回答过于复杂而且不够理想。我觉得这样更好:

proc isNestedList l {
    foreach a $l {
        if {$a ne [lindex $a 0]} {
            return true
        }
    }
    return false
}