2015-07-20 125 views
1

我有一个带有动态“键”和与它们相关的值的数组。 我想基于该值对数组进行排序,并希望能够从已排序的数组中检索'keys'。 例如,说我有,基于值的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)感兴趣,以便进一步处理。

我无法在互联网上找到这种具有动态生成密钥的阵列。 任何帮助,非常感谢。

谢谢。

+0

感谢所有为您的建议。但我使用的tcl版本8.5不支持lmap,stride等 –

回答

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]] 

这种方法打包的元素融入“对“进行排序,对打包列表进行排序,然后将其解压缩到平面列表中,以便像上面那样用作字典。

文档:arrayconcatdictforeachlappendlistlsortset

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指示排序按子列表的第二个元素进行排序(Tcl具有基于列表0的列表)。 -integer只是指示我们正在整理整数(而不使用字典排序)。你只需要在列表拿到钥匙:

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

您可以结合上述的一个循环,如果你想(我结合循环和第二线,将第一行会让它看起来有点太多):

foreach n [lsort -index 1 -integer -decreasing $key_value] { 
    puts [lindex $n 0] 
} 
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 
% 

你可以让他们与期待的顺序列表,然后试图进一步运用你的逻辑。