我有一个带有动态键的数组'和与之相关的价值观。 我想根据值对数组进行排序,并希望能够检索'键。从排序的数组。 例如,说我有,
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)感兴趣,以便进一步处理。
我无法在互联网上找到具有动态生成密钥的此类数组。 非常感谢任何帮助。
感谢。
答案 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;,对打包列表进行排序,然后将其解压缩到一个平面列表中,以便可用作上面的字典。