2014-01-15 53 views
0

字典濾波器我有這樣限定的dictionnary:TCL:在嵌套dictionnary

dict set lag_in lagId 1       
    dict set lag_in m1  port "1/2"   
    dict set lag_in m1  ixPort $ix_port(1)  
    dict set lag_in m2  port "1/20"   
    dict set lag_in m2  ixPort $ix_port(2)  
    dict set lag_in m3  port "1/17"   
    dict set lag_in m3  ixPort $ix_port(17) 
    dict set lag_in itf1  vlan 1 
    dict set lag_in itf1  ip  10.0.0.1/24 
    dict set lag_in itf1  vlan 20 
    dict set lag_in itf1  ip  10.1.1.20/21 

我希望定義返回一個滯後構件取決於端口或ixPort上一個PROC。第一次嘗試:

proc getLagMember { dictionnary args } { 
    set opts(port)  "" 
    getopt opts $args 

    dict for { key val } $dictionnary {           
     if { [regexp {m[1-4]} $key] } {           
      if { [dict get $dictionnary $key port] == $opts(port) } {    
       return [dict filter $dictionnary key $key] 
      } 
     } 
    } 
} 

但這並不做什麼,我想:

% getLagMember $lag_in -port "1/2" 
m1 {port 1/2 ixPort {1 4 1}} ;# I am expecting port 1/2 ixPort {1 4 1} 

於是,我就modifiy的return這樣的:

return [dict filter [dict filter $dictionnary key $key] key $key] 

但我仍然沒有我想要的是。我究竟做錯了什麼 ? 有沒有更好的方法來實現我想要的?

編輯:感謝格倫我帶着這個進程內,但它不會與-ixPort選項

proc getLagMember { dictionnary args } { 
    set opts(port) "" 
    set opts(ixPort) "" 
    getopt opts $args 

    parray opts 

    dict for { key val } $dictionnary {           
     if {[catch {dict get $val port} port] == 0 && $port eq $opts(port) || [catch {dict get $val ixPort} ixPort] == 0 && $ixPort eq $opts(ixPort)} { 
      return $val            
     } 
    } 
} 

輸出與-port工作:

% getLagMember $lag_in -port 1/2 
opts(ixPort) = 
opts(port) = 1/1 
port 1/1 ixPort {1 4 1} 

輸出與-ixPort

% getLagMember $lag_in -ixPort {1 4 1} 
opts(ixPort) = 1 4 1 
opts(port) = 
ixPort {1 4 1} 

回答

1

嘗試

proc getLagMember { dictionnary args } { 
    array set opts {-port ""} 
    array set opts $args 

    dict for { key val } $dictionnary {           
     if {[catch {dict get $val port} port] == 0 && $port eq $opts(-port)} { 
      return $val 
     } 
    } 
} 

更新:我不明白你看到相同的不正確的結果:

tclsh << 'ENDSCRIPT' 
    array set ix_port {1 {1 4 1} 2 2 17 17} 
    dict set lag_in lagId 1       
    dict set lag_in m1  port "1/2"   
    dict set lag_in m1  ixPort $ix_port(1)  
    dict set lag_in m2  port "1/20"   
    dict set lag_in m2  ixPort $ix_port(2)  
    dict set lag_in m3  port "1/17"   
    dict set lag_in m3  ixPort $ix_port(17) 
    dict set lag_in itf1  vlan 1 
    dict set lag_in itf1  ip  10.0.0.1/24 
    dict set lag_in itf1  vlan 20 
    dict set lag_in itf1  ip  10.1.1.20/21 

    proc checkAttribute {dict attr} { 
     upvar 1 opts opts 
     expr {[catch {dict get $dict $attr} value] == 0 && $value eq $opts(-$attr)} 
    } 

    proc getLagMember { dictionnary args } { 
     array set opts {-port "" -ixPort ""} 
     array set opts $args 

     dict for { key val } $dictionnary {           
      if {[checkAttribute $val port] || [checkAttribute $val ixPort]} { 
       return $val 
      } 
     } 
    } 

    puts [getLagMember $lag_in -port 1/2] 
    puts [getLagMember $lag_in -ixPort {1 4 1}] 
ENDSCRIPT 
port 1/2 ixPort {1 4 1} 
port 1/2 ixPort {1 4 1} 

說,你不這樣做,是嗎?

getLagMember $lag_in -ixPort 1 4 1 
+0

用於'catch'的很好的例子,謝謝:) –

+0

我剛剛注意到這不適用於ixPort鍵。我只是用下面的方法替換了if:if {[catch {dict get $ val ixPort} ixPort] == 0 && $ ixPort eq $ opts(ixPort)} {'並且返回'ixPort {1 4 1}' '端口1/2 ixPort {1 4 1}'當我使用選項'-ixPort'時 –

+0

使用'$ opts(-ixPort)'*連字符 –