Сортировка списков TCL по значениям в предварительно определенном списке - PullRequest
2 голосов
/ 06 ноября 2019

На самом деле в C # существует существующий вопрос для этого, так что надеюсь, что кто-то может дать мне решение TCL. Сортировка списка на основе предварительно отсортированного списка

У меня есть список, который уже отсортирован. Скажем, мой отсортированный список:

{"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 сохранить заказ.

1 Ответ

2 голосов
/ 06 ноября 2019

Вы можете использовать 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 сделать это; есть случаи злых граней, которые обычно не имеют значения при выполнении видимых для пользователя выводов).


Вместо этого вы можете использовать -indices для lsort, чтобы избежать создания всех этих кортежей.

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, нокод намного длиннее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...