如何按值对Tcl数组进行排序?

时间:2015-12-02 10:03:59

标签: arrays sorting tcl

如何对Array输出进行排序 样本输入来自
把“$ word $ count($ word)”}

示例输入

Roger 15
Martin 18
Jemmy 16
Jon 12
Sara 12

预期输出

Martin 18
Jemmy 16
Roger 15
Jon 12
Sara 12

3 个答案:

答案 0 :(得分:3)

Tcl的数组总是未排序,实际上,当您添加元素时(重建基础哈希表时),元素的顺序会不时发生变化。要获得所需的输出,您最好获取数组的内容并使用lsort -stride 2选项:

# Convert the array to a Tcl list
set contents [array get count]

# First sort by name, as a secondary key
set contents [lsort -stride 2 -index 0 $contents]
# Then sort by count, descending, as a primary key
set contents [lsort -stride 2 -index 1 -integer -decreasing $contents]

# Print the values
foreach {name score} $contents {
    puts "$name $score"
}

-stride选项需要 Tcl 8.6。

在早期版本的Tcl中,您必须将内容打包到list个元组中:

# Convert the array to a list of pairs
set contents {}
foreach {name score} [array get count] {
    lappend contents [list $name $score]
}

# Do the sorting
set contents [lsort -index 0 $contents]
set contents [lsort -index 1 -integer -decreasing $contents]

# Print the values
foreach pair $contents {
    # Unpack; *not* needed here, but useful for anything more complicated
    foreach {name score} $pair break
    # You could use “lassign $pair name score” but you're on 8.4
    puts "$name $score"
}

请注意,Tcl 8.4是不受支持的软件,即使是安全问题也没有,并且8.5只剩下一年或两年的延长支持生命周期。我们持有人手的时间有限......

答案 1 :(得分:1)

你可能有这样的东西

array set count { Roger 15 Martin 18 Jemmy 16 Jon 12 Sara 12 }
foreach word [array names count] {puts "$word $count($word)"}
Jemmy 16
Sara 12
Jon 12
Martin 18
Roger 15

你想要做的是将数组转换为一个列表,成对地跳过它并根据数字对这些对进行排序:

foreach {name num} \
        [lsort -integer -decreasing -stride 2 -index 1 [array get count]] \
        {puts "$name $num"}
Martin 18
Jemmy 16
Roger 15
Sara 12
Jon 12

参考文献:
http://www.tcl.tk/man/tcl8.6/TclCmd/lsort.htm
http://www.tcl.tk/man/tcl8.6/TclCmd/foreach.htm

答案 2 :(得分:0)

Tcl的解决方案< 8.6:

鉴于

array set count {Roger 15 Martin 18 Jemmy 16 Jon 12 Sara 12}

获得排序的方法是

set L [list]
foreach {k v} [array get count] {
    lappend L [list $k $v]
}
foreach e [lsort -index 1 -decreasing -integer $L] {
    lassign $e k v
    puts "$k $v"
}

说明:

  1. 使用array get获取交错键和值的平面列表。
  2. 从中,生成一个键/值对的列表 - 一个列表列表。
  3. 根据该列表,使用传递它的lsort命令对其进行排序 -index 1选项使lsort解释了元素 list将其排序为列表,并在索引1处使用它们的元素 (第2位)进行分类。
  4. 要打印出已排序列表的元素,您需要提取 键和每个键的值。最简单的方法是使用 lassign但是如果你有Tcl< 8.5你可以使用 foreach {k v} $e break使用技巧或直接访问元素 lindex $e 0lindex $e 1分别获取密钥和值。