tcl:嵌套字典上的dict过滤器

时间:2014-01-15 20:31:46

标签: dictionary tcl proc

我有一个这样定义的词典:

  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}

所以我试着像这样修改return

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

但我仍然没有我想要的东西。我究竟做错了什么 ? 是否有更好的方法来实现我想要的目标?

编辑:感谢Glenn,我来了这个proc,但是它不适用于-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 个答案:

答案 0 :(得分: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