如何在tcl中迭代嵌套列表?

时间:2015-07-15 08:48:03

标签: tcl

tcl

中有一个嵌套列表x
set x {{A 0} {B 1} {C 2} {D 3}}

如何迭代并打印此嵌套列表中的所有元素?

5 个答案:

答案 0 :(得分:2)

很容易扩展Dinesh的答案,使其真正递归:

set x {{A 0} {B 1} {C 2} {D 3} {4 {F G}}}; # Have added one more element

proc printListElem {myList {level 1}} {
    foreach elem $myList {
        puts "[string repeat "+" $level] $elem"
        if {[llength $elem] > 1} {
            printListElem $elem [expr {$level + 1}]
        }
    }
}

printListElem $ x

+ A 0
++ A
++ 0
+ B 1
++ B
++ 1
+ C 2
++ C
++ 2
+ D 3
++ D
++ 3
+ 4 {F G}
++ 4
++ F G
+++ F
+++ G

答案 1 :(得分:0)

set x {{A 0} {B 1} {C 2} {D 3} {6 {F G}}}

set y {{{{1 2 {3 4}}}}}

array set myarr {}
set count 0
proc printListElem {myList} {
    global myarr count
    for {set i 0} {$i <[llength $myList]} {incr i} {
        set currentElem [lindex $myList $i]
        if {![info exists myarr($count,${currentElem})]} {
            incr count
            set myarr($count,${currentElem}) 1
            printListElem $currentElem
        } else {
            incr count -1
            break
        }
    }
}

printListElem $y
foreach idx [lsort [array names myarr]] {
    lassign [split $idx ,] key value
    puts "[string repeat "+" $key]$value"
}

这个将适用于所有嵌套级别的列表,输出将显示为,

+{{1 2 {3 4}}}
++{1 2 {3 4}}
+++1 2 {3 4}
++++1
++++2
++++3 4
+++++3
+++++4

此处显示的+数表示列表元素的嵌套级别。 (感谢Mr.Glenn的想法)。这可能不是有效的,但也可以这样做。

答案 2 :(得分:0)

如果我们知道列表深度,我们可以嵌套一些foreach次调用:

foreach a $x {
    foreach b $a {
        puts "--> $b"
    }
}

但是在Tcl中不存在一般“迭代所有可能的嵌套列表”,因为该概念与Tcl的类型模型不兼容。你实际上不应该以某种方式思考价值观,这是一个值得提问的明智问题。您不构建任意树:您构建特定的树,其中的级别对手头的问题有意义。

(关键问题是red hot cat同时是3项目列表和11个字符串。)

答案 3 :(得分:0)

我看到人们试图递归迭代并提出通用解决方案,我很确定有些人可能不同意这一点,但问题的答案是“如何迭代并打印这个嵌套列表?“很简单。

该列表包含4个元素“A 1”,“B 2”,“C 3”,“D 4”,所以答案是:

% set x {{A 0} {B 1} {C 2} {D 3}}
{A 0} {B 1} {C 2} {D 3}

% foreach item $x {
    puts $item
}
A 0
B 1
C 2
D 3

假设有人希望对个别值进行某些操作,则可以使用lindexlassign拆分它们,例如

% foreach item $x {
    lassign $item char num
    puts "char = $char, num = $num"
}
char = A, num = 0
char = B, num = 1
char = C, num = 2
char = D, num = 3

foreach也可以采用多个值,因此也可以这样做:

foreach item $x {
    foreach {char num} $item {
        puts "char = $char, num = $num"
    }
}

在实践中,不会有随机级别的嵌套列表来存储有用的数据,但如果实际上恰好有这样的数据,那么可能值得研究dict

举个例子:

 % set x {A {B 2} C {D {E 5}} F 6}
 A {B 2} C {D {E 5}} F 6
 % dict get $x A
 B 2
 % dict get $x A B
 2
 % dict get $x C D E
 5
 % dict get $x F
 6

答案 4 :(得分:0)

如果您愿意完全放弃所有嵌套级别的跟踪,则可以使用此方法完全折叠所有嵌套列表级别(除非在列表的字符串值中使用 {} 除外)那些也将被淘汰

set x {{A 0} {B 1} {C 2} {D 3} {6 {F G}}} 
set xn [string map {"{" "" "}" ""} $x] 


puts [join $xn "\n"]