如何在没有变更单的情况下获得阵列输出?

时间:2017-08-25 07:30:13

标签: tcl

我得到一个数组:

array set arrayA {1 a 3 b 2 x 4 g}

如何在不改变订单的情况下获得输出?

foreach {key value} [array get arrayA] {
    puts $key
    puts $value
}

如何获得低于输出,谢谢!

1
a
3
b
2
x
4
g

2 个答案:

答案 0 :(得分:1)

Tcl数组不保留其元素的插入顺序(但是,确实如此)。要按顺序列出元素,您需要提供所需的订单,例如通过排序:

set my_order [lsort -integer [array names arrayA]]
foreach key $my_order {
    puts $key
    puts $arrayA($key)
}

但那不是你想要的。

通过在创建时存储名称(以及在添加新名称时更新名称列表),可以快速,简单地保留数组的插入顺序:

set my_order {1 3 2 4}
array set arrayA {1 a 3 b 2 x 4 g}

foreach key $my_order {
    puts $key
    puts $arrayA($key)
}

使用痕迹的速度越来越快,越来越肮脏,越来越精细和健壮。

这是使用跟踪保持数组的插入顺序顺序的一种方法。跟踪可以设置为激活(运行处理程序) array 操作(在数组上调用array命令),读取操作(例如{{1 }},我们不会打扰那些操作(例如puts $arrayA(1)array set arrayA {1 z}取消设置操作(例如{{1对我们来说最有趣的操作是 write 操作,这些操作可能会向数组中添加新元素,而取消设置操作会将它们取出来。

我们可以为每个操作设置一个处理程序,或者为它们提供一个大处理程序;我会选择后者。

set arrayA(1) z

我希望能够处理最重要的事情。现在要设置跟踪本身。请注意,为一个变量设置了跟踪,在本例中为三个不同的操作。如果与一个或多个这些操作匹配的变量发生了某些事情,则将为每个操作调用一次处理程序。我们使用固定的第一个参数来告诉处理程序哪个变量保存了插入顺序。

unset array(1)

现在我们可以创建数组并在其中添加或删除成员,并按照插入顺序打印元素,如下所示:

proc arrayOrder {varName name1 name2 op} {
    # make 'var' a link to the global variable named in the first argument
    upvar #0 $varName var
    # the three following arguments will be supplied when the trace fires:
    # 'name2' is the element name, and 'op' is the operation (array, write, or
    # unset)
    #
    # not doing anything particular with $op eq "array": you might want to
    # experiment with it to see if you have use for it
    if {$op eq "write"} {
        # is the name already in the order list?
        if {$name2 ni $var} {
            # no, it isn't, meaning it's a new element that should be added to
            # the order list
            lappend var $name2
        }
    }
    if {$op eq "unset"} {
        if {$name2 eq {}} {
            # the whole array was unset: empty the order list
            set var {}
        } else {
            # just one element was unset: remove the name from the order list
            set idx [lsearch -exact $var $name2]
            set var [lreplace $var $idx $idx]
        }
    }
}

请注意,如果取消设置整个数组,则跟踪会消失,您需要恢复它。

文档: arrayeq (operator)foreachiflappendlreplacelsearchlsortni (operator)procputssettraceunsetupvar

答案 1 :(得分:0)

正如彼得所说,词典保留了秩序:

set d [dict create {*}{1 a 3 b 2 x 4 g}]
dict for {key value} $d {puts $key; puts $value}