tcl

# Is there any better way to sort elements in a list?

here is the list

``````"_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"
``````

to be sorted to

``````"_7_to_0_k1"
"_7_to_0_k2"
"_7_to_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"
``````

note : in this list 7_to_0 represents 7_6_5_4_3_2_1_0 tried this custom sort to sort by last two characters but i think i need to modify it to search for the whole string.

``````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]
``````

Solution

• Let's do a "decorate-sort-undecorate" technique:

``````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}]
``````