基于值的Tcl数组排序

时间:2015-07-20 16:33:38

标签: arrays sorting hashmap tcl

我有一个带有动态键的数组'和与之相关的价值观。 我想根据值对数组进行排序,并希望能够检索'键。从排序的数组。 例如,说我有,

for {set i 0} {$i < [db_get_nrows $rs]} {incr i} {
    set x [db_get_col $rs $i abc]
    set ARRAY_A($x) [db_get_col $rs $i def]
}

所以,我的数组看起来像,

ARRAY_A(111) 10
ARRAY_A(222) 50
ARRAY_A(333) 20

现在,我想根据它的值(首先是50,然后是20,然后是10)对这个数组进行排序。然后我对它的密钥(222,333和111)感兴趣,以便进一步处理。

我无法在互联网上找到具有动态生成密钥的此类数组。 非常感谢任何帮助。

感谢。

3 个答案:

答案 0 :(得分:3)

好吧,我只是想提一下,你不能对数组进行排序,因为它们确实没有固定的顺序,但是以一种方式保存,使得解释器更容易/更快地检索值。

如果你想按照值的顺序获取数组的键,你可以使用类似的东西:

set key_value [lmap {key val} [array get ARRAY_A] {list $key $val}]
set key_value [lsort -index 1 -integer -decreasing $key_value]

列表key_value现在保存数组的键/值对,按值递减排序。 -index 1表示排序按子列表的第2个元素排序(Tcl列出了基于0的列表)。 -integer只是指示我们正在排序整数(而不是使用字典排序)。您只需要从列表中获取密钥:

foreach n $key_value {
    puts [lindex $n 0]
}

如果需要,你可以在一个循环中组合上述内容(我将循环和第二行结合起来,添加第一行会使它看起来有点太多):

foreach n [lsort -index 1 -integer -decreasing $key_value] {
    puts [lindex $n 0]
}

答案 1 :(得分:2)

% set tcl_version
8.6
% array set n {111 10 222 50 333 20}
% parray n
n(111) = 10
n(222) = 50
n(333) = 20
% set l [array get n]
333 20 222 50 111 10
% lsort -stride 2 -integer -index 1 $l
111 10 333 20 222 50
% lsort -stride 2 -integer -decreasing -index 1 $l
222 50 333 20 111 10
% 

您可以将它们作为预期订单列表,然后尝试进一步应用您的逻辑。

答案 2 :(得分:2)

这部分答案主要是Dinesh答案的附录,本身并不完整。

一旦创建了包含按值排序的数组元素的列表,就可以将它放在字典中(这是另一种关联列表结构):

set d [lsort -stride 2 -integer -decreasing -index 1 $l]

字典将保留插入顺序,并允许轻松访问例如钥匙:

dict keys $d
# -> 222 333 111

<强> ETA

如果您无法使用lmap-stride,您仍然可以生成如下字典:

set pairs {}
foreach {a b} [array get ARRAY_A] {
    lappend pairs [list $a $b]
}
set DICT_A [concat {*}[lsort -index 1 -integer -decreasing $pairs]]

此方法将元素打包成&#34;对&#34;,对打包列表进行排序,然后将其解压缩到一个平面列表中,以便可用作上面的字典。

文档:arrayconcatdictforeachlappendlistlsort,{{3 }}