按预定义列表中的值对 TCL 列表进行排序

Sorting TCL lists by values in a pre-defined list

在 C# 中实际上存在一个问题,所以希望有人能给我 TCL 解决方案。 Sort a List based on a Pre-Sorted List

我有一个已经排序的列表。比如说,我的排序列表是

{"Junior Developer" "Developer" "Senior Developer" "Project Lead"}

现在,我想按照与上述列表相同的顺序对上述列表的任何子集进行排序。也就是说,如果我有

作为输入
{"Developer" "Junior Developer"}

我希望输出为

{"Junior Developer" "Developer"}

如果输入是

{"Project Lead" "Junior Developer" "Developer"}

然后我希望输出为

{"Junior Developer" "Developer" "Project Lead"}

我看到 lsort 有一个 -command 选项,但已经阅读了很多评论说它没有很好的性能,所以想知道是否有另一种方法可以使用 dict 保留顺序。

您可以使用 lsearch 将索引放入排序列表中,然后将它们用作排序规则键:

set orderList {"Junior Developer" "Developer" "Senior Developer" "Project Lead"}
set original {"Developer" "Junior Developer"}

set keyed [lmap value $original {list $value [lsearch -exact $orderList $value]}]
set sortedKeyed [lsort -index 1 -integer $keyed]
set sorted [lmap value $sortedKeyed {lindex $value 0}]

puts "$original -> $sorted"
# "Developer" "Junior Developer" -> {Junior Developer} Developer

不建议在输出中用双引号将值括起来;它不是规范的列表引用样式(强制 Tcl 这样做是 hard;在执行用户可见的输出时,有一些邪恶的边缘情况通常无关紧要)。


您可以改为使用 lsort-indices 选项来避免构建所有这些元组。

set orderList {"Junior Developer" "Developer" "Senior Developer" "Project Lead"}
set original {"Developer" "Junior Developer"}

set indexes [lmap value $original {lsearch -exact $orderList $value}]
set sortedIndexes [lsort -indices -integer $indexes]
set sorted [lmap idx $sortedIndexes {lindex $original $idx}]

puts "$original -> $sorted"
# "Developer" "Junior Developer" -> {Junior Developer} Developer

你可以用foreach代替lmap,但是代码比较啰嗦。