2009-08-24 97 views
4

如何創建並通過TCL哈希的遍歷一個哈希表?如何在TCL中創建並遍歷散列哈希值?

如果我有這樣的數據:

foo = { 
    a => { 
     aa => { aa1 aa2 aa3 } 
     ab => { ab1 ab2 ab3 } 
     ac => { ac1 ac2 ac3 } 
    } 
    b => { 
     ba => { ba1 ba2 ba3 } 
     bb => { bb1 bb2 bb3 } 
     bc => { bc1 bc2 bc3 } 
    } 
    c => { 
     ca => { ca1 ca2 ca3 } 
     cb => { cb1 cb2 cb3 } 
     cc => { cc1 cc2 cc3 } 
    } 
} 

如何創建通過一次插入一個葉子節點的數據項這樣的哈希值。喜歡的東西:

lappend富(一)(AB) 「AB1」

那我怎麼遍歷所有數據元素?像:

foreach key in foo { 
    foreach sub_key in foo($key) { 
     foreach elem in foo($key)($sub_key) { 
      puts "foo\($key\)\($sub_key\) is $elem" 
     } 
    } 
} 

編輯: 不幸的是,我沒有進入到較新的「字典」建設。

+0

我分開我的答案突出非字典解決方案。 – 2009-08-24 20:43:26

回答

7

如果你不使用Tcl 8.5,那麼你可以使用數組。需要注意的是陣列是一維的,但關鍵是,可用於假多維度的任意字符串:

array set foo {} 
foreach first {a b c} { 
    foreach second {a b c} { 
     foreach third {1 2 3} { 
      lappend foo($first,$first$second) "$first$second$third" 
     } 
    } 
} 
parray data 

,並將其輸出 - 注意:數組鍵,不像字典鍵,是無序:

foreach key [array names foo] { 
    foreach elem $foo($key) { 
     puts "$key\t$elem" 
    } 
} 

如果你給出的鍵(例如「b」和「BC」),你可以得到正是如此值:

set key1 b 
set key2 bc 
foreach elem $foo($key1,$key2) {puts $elem} 
8

假設你正在使用Tcl 8.5+,字典是要走的路:

定義詞典做法僅僅是:

set foo { 
    a { 
     aa { aa1 aa2 aa3 } 
     ab { ab1 ab2 ab3 } 
     ac { ac1 ac2 ac3 } 
    } 
    b { 
     ba { ba1 ba2 ba3 } 
     bb { bb1 bb2 bb3 } 
     bc { bc1 bc2 bc3 } 
    } 
    c { 
     ca { ca1 ca2 ca3 } 
     cb { cb1 cb2 cb3 } 
     cc { cc1 cc2 cc3 } 
    } 
} 

或以編程方式進行定義:

set foo [dict create] 
foreach first {a b c} { 
    dict update foo $first subdict { 
     foreach second {a b c} { 
      foreach third {1 2 3} { 
       dict lappend subdict "$first$second" "$first$second$third" 
      } 
     } 
    } 
} 

並輸出:

dict for {key1 subdict} $foo { 
    dict for {key2 list} $subdict { 
     foreach elem $list { 
      puts "$key1\t$key2\t$elem" 
     } 
    } 
} 

編輯:移動所述陣列的溶液(非字典)到單獨的答案。

+0

我沒有權限訪問'dict'結構..謝謝你的回答。 – 2009-08-24 20:03:25

1

如果你只是想通過一個字典迭代(這是一個簡單的鍵值對列表)w ithout的字典命令,那麼可以簡單地使用的foreach的迷死:

set foo { 
    a { 
    aa { aa1 aa2 aa3 } 
    ab { ab1 ab2 ab3 } 
    ac { ac1 ac2 ac3 } 
    } 
    b { 
    ba { ba1 ba2 ba3 } 
    bb { bb1 bb2 bb3 } 
    bc { bc1 bc2 bc3 } 
    } 
    c { 
    ca { ca1 ca2 ca3 } 
    cb { cb1 cb2 cb3 } 
    cc { cc1 cc2 cc3 } 
    } 
} 

foreach {key value} $foo { 
    foreach {sub_key sub_value} $value { 
    foreach elem $sub_value { 
     puts "foo\($key\)\($sub_key\) is $elem" 
    } 
    } 
} 

在另一方面,在插入元件的一個在一個時間是沒有字典命令痛苦:

set foo {} 
lappend foo a {} 
set a_index [lsearch $foo a] 
set a_value_index [expr {$a_index+1}] 
set a_value [lindex $foo $a_value_index] 
lappend a_value aa {} 
lset foo $a_value_index $a_value 
# it is now too painful for me to continue :-(

好在可以使用一個純Tcl實現字典命令:forward-compatible dict

1

如果你不具備的Tcl 8.5字典的奢華,使用鍵列表命令來完成這項工作。您可以通過以下其中一個條款來搜索:keylget,keylset。

package require Tclx 

# Create the nested structure 
catch {unset foo} 
foreach key1 {a b c} { 
    foreach key2 {a b c} { 
     catch {unset element} 
     foreach key3 {1 2 3} { 
      lappend element "$key1$key2$key3" 
     } 
     keylset foo $key1.$key1$key2 $element 
    } 
} 

# Access the nested structure 
foreach key1 {a b c} { 
    foreach key2 {a b c} { 
     set elementList [keylget foo $key1.$key1$key2] 
     foreach element $elementList { 
      puts "foo\\$key1\\$key1$key2\\$key3 = $element" 
     } 
    } 
} 

# 
# Access examples 
# 

# Access a block of data 
puts "foo\\a = [keylget foo a]" 
# Access a nested block of data 
puts "foo\\b\\ba = [keylget foo b.ba]" 
# Access an individual element, remember that Tcl's list index is 0 based 
puts "foo\\c\\cb\\1 = [lindex [keylget foo c.cb] 0]"