如何按值对 Tcl 数组进行排序?
How do I sort a Tcl array by values?
例如如何对数组输出进行排序
来自
的样本输入
放“$word $count($word)”}
示例输入
Roger 15
Martin 18
Jemmy 16
Jon 12
Sara 12
预期输出
Martin 18
Jemmy 16
Roger 15
Jon 12
Sara 12
你可能有这样的事情
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
Tcl 的数组总是 未排序的 ,事实上,当您在其中添加元素时,元素的顺序会不时发生变化(当底层哈希 table 是重建)。要获得所需的输出,最好获取数组的内容并使用 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 只剩下一两年的延长支持寿命。我们握住人们的手的时间是有限度的……
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
. 获取交错键和值的平面列表
- 从中生成一个 key/value 对 的列表——列表的列表。
- 给定该列表,使用传递给它的
lsort
命令对其进行排序
-index 1
选项使 lsort
解释
list 它按列表排序,并在索引 1 处使用它们的元素
(第 2 个位置)用于排序。
- 要打印出排序列表的元素,您需要提取
键和每个返回的值。最简单的方法是使用
lassign
但如果您的 Tcl < 8.5,您可以使用
foreach {k v} $e break
欺骗或直接访问元素使用
lindex $e 0
和 lindex $e 1
分别获取键和值。
例如如何对数组输出进行排序
来自
的样本输入
放“$word $count($word)”}
示例输入
Roger 15
Martin 18
Jemmy 16
Jon 12
Sara 12
预期输出
Martin 18
Jemmy 16
Roger 15
Jon 12
Sara 12
你可能有这样的事情
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
Tcl 的数组总是 未排序的 ,事实上,当您在其中添加元素时,元素的顺序会不时发生变化(当底层哈希 table 是重建)。要获得所需的输出,最好获取数组的内容并使用 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 只剩下一两年的延长支持寿命。我们握住人们的手的时间是有限度的……
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
. 获取交错键和值的平面列表
- 从中生成一个 key/value 对 的列表——列表的列表。
- 给定该列表,使用传递给它的
lsort
命令对其进行排序-index 1
选项使lsort
解释 list 它按列表排序,并在索引 1 处使用它们的元素 (第 2 个位置)用于排序。 - 要打印出排序列表的元素,您需要提取
键和每个返回的值。最简单的方法是使用
lassign
但如果您的 Tcl < 8.5,您可以使用foreach {k v} $e break
欺骗或直接访问元素使用lindex $e 0
和lindex $e 1
分别获取键和值。