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
}
如何有效地测试 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
}