【问题标题】:Tcl array sorting based on values基于值的 Tcl 数组排序
【发布时间】:2015-10-09 21:13:30
【问题描述】:

我有一个包含动态“键”和与之关联的值的数组。 我想根据值对数组进行排序,并希望能够从排序后的数组中检索“键”。 例如,假设我有,

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)感兴趣,以便进一步处理。

我在互联网上找不到很多动态生成键的数组。 非常感谢任何帮助。

谢谢。

【问题讨论】:

  • 感谢大家的建议。但我使用的是不支持 lmap、stride 等的 tcl 版本 8.5。

标签: arrays sorting hashmap tcl


【解决方案1】:

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

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

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】:

    这部分答案主要是对 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 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
      % 
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-01
        • 2021-01-13
        • 2021-12-11
        • 2014-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多