如何对Array输出进行排序
样本输入来自
把“$ word $ count($ word)”}
示例输入
Roger 15
Martin 18
Jemmy 16
Jon 12
Sara 12
预期输出
Martin 18
Jemmy 16
Roger 15
Jon 12
Sara 12
答案 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"
}
说明:
array get
获取交错键和值的平面列表。lsort
命令对其进行排序
-index 1
选项使lsort
解释了元素
list将其排序为列表,并在索引1处使用它们的元素
(第2位)进行分类。lassign
但是如果你有Tcl< 8.5你可以使用
foreach {k v} $e break
使用技巧或直接访问元素
lindex $e 0
和lindex $e 1
分别获取密钥和值。