有没有更好的方法对列表TCL中的元素进行排序?

问题描述 投票:0回答:2

这是列表 “_7_到_0_k1” “_7_到_0_k3” “_7_6_5_0_k4” “_3_2_k6” “_4_3_2_1_k4” “_1_k5” “_3_2_k5” “_0_k5” “_3_2_k7” “_4_k5” “_5_k5” “_7_6_k5” “_7_6_k6” “_7_到_0_k2” “_7_6_k7”

要排序为 “_7_到_0_k1” “_7_到_0_k2” “_7_到_0_k3” “_7_6_5_0_k4” “_0_k5” “_4_3_2_1_k4” “_1_k5” “_3_2_k5” “_3_2_k6” “_3_2_k7” “_4_k5” “_5_k5” “_7_6_k5” “_7_6_k6” “_7_6_k7”

注意:在此列表中 7_to_0 代表 7_6_5_4_3_2_1_0 尝试了这种自定义排序来按最后两个字符排序,但我认为我需要修改它以搜索整个字符串。

proc sort_by_last_two {a b} {
    set a_last_two [string range $a end-1 end]
    set b_last_two [string range $b end-1 end]
    return [string compare $a_last_two $b_last_two]
}
set sorted_list [lsort -command sort_by_last_two $my_lis]
tcl
2个回答
0
投票

让我们做一个“装饰-排序-取消装饰”技术:

set theList {"_7_to_0_k1" "_7_to_0_k3" "_7_6_5_0_k4" "_3_2_k6" "_4_3_2_1_k4" "_1_k5" "_3_2_k5" "_0_k5" "_3_2_k7" "_4_k5" "_5_k5" "_7_6_k5" "_7_6_k6" "_7_to_0_k2" "_7_6_k7"}

set decorated [lmap elem $theList {list $elem [lrange [split $elem "_"] end-1 end]}]
set decoratedSorted [lsort -index end $decorated]
set sortedList [lmap item $decoratedSorted {lindex $item 0}]

0
投票

您可以为

lsort
提供自定义比较函数,以考虑整个字符串。

proc customCompare {a b} {
    set lastA [lindex [split $a "_"] end]
    set lastB [lindex [split $b "_"] end]
    return [expr {$lastA - $lastB}]
}

set inputList {"_7_to_0_k1" "_7_to_0_k3" "_7_6_5_0_k4" "_3_2_k6" "_4_3_2_1_k4" "_1_k5" "_3_2_k5" "_0_k5" "_3_2_k7" "_4_k5" "_5_k5" "_7_6_k5" "_7_6_k6" "_7_to_0_k2" "_7_6_k7"}

set sortedList [lsort -command customCompare $inputList]

puts $sortedList

它将下划线字符上的元素分开,并以数字方式比较最后部分。然后,它根据这个自定义比较函数对列表进行排序。

© www.soinside.com 2019 - 2024. All rights reserved.