代码之家  ›  专栏  ›  技术社区  ›  Gert Gottschalk

TCL跨维数组循环

  •  0
  • Gert Gottschalk  · 技术社区  · 6 年前

    foreach 循环,因为我必须做一些家务和打印的一路上。由于缺少条目,我将使用一些 info exists array names -glob 但是,这将返回复合索引(TCL实际上并不知道多维数组)。我正在寻找一种最好的方法来分解这个复合指数,就好像有一个 -stride -index 选择好像是 lsort .

    -索引 选择 array namees )这表达了我的想法。

    array set ar { x1,y1 v11 x1,y2 v12 x1,y3 v13
                   x2,y1 v21           x2,y3 v13
                   x3,y1 v31 x3,y2 v32 x3,y3 v33
                   x4,y1 v41 x4,y2 v42 x4,y3 v43 }
    
    foreach x { x1 x2 x3 x4 } {
      foreach y [ array names ar -glob ${x}* -index 1 ] {
        puts $y
      }
    }
    

    预期产量

    y1
    y2
    y3
    y1  \
    y3  / => Note missing entry
    y1
    y2
    y3
    y1
    y2
    y3
    

    更新:

    查看建议使用 split array names 或者可以做点什么 foreach公司 使这条河更顺。

    分裂

    foreach x { x1 x2 x3 x4 } {
      foreach yy [ array names ar -glob ${x}* ]  {
        set y [ lindex [ split $yy , ] 1 ]
        puts $y
      }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Donal Fellows    6 年前

    好吧,你可以很容易地得到主键和次键的列表:

    # You might choose different sorting rules…
    set xs [lsort -unique [lmap xy [array names ar] {
        lindex [split $xy ","] 0
    }]]
    set ys [lsort -unique [lmap xy [array names ar] {
        lindex [split $xy ","] 1
    }]]
    

    然后您可以使用嵌套 foreach info exists 要处理稀疏性:

    foreach x $xs {
        foreach y $ys {
            if {[info exists ar($x,$y)]} {
                ...
                ...
            }
        }
    }
    

    8.6还没有?(开始节目吧!)你可以收集 xs ys 这样地:

    set xs {}
    set ys {}
    foreach xy [array names ar] {
        lassign [split $xy ","] x y
        lappend xs $x
        lappend ys $y
    }
    set xs [lsort -unique $xs]
    set ys [lsort -unique $ys]