proc lsort-indices list {
if [llength $list] {
set i -1
foreach e $list {lappend tmp [list [incr i] $e]}
foreach e [lsort -index 1 $tmp] {lappend res [lindex $e 0]}
set res
}
}if 0 {Testing:
% lsort-indices {c b a}
2 1 0
% lsort-indices {}
% lsort-indices {a a a}
0 1 2RS removed the initialisations of tmp and res, but then had to guard the body with a one-armed if - it implies "else {}", which is the correct return value for an empty list.Lars H had this solution, which is said to be up to a third faster:
proc lsort-indices itemL {
set pairL [list]
foreach item $itemL {
lappend pairL [list $item [llength $pairL]]
}
set indexL [list]
foreach pair [lsort -index 0 $pairL] {
lappend indexL [lindex $pair 1]
}
return $indexL
}wdb This version allows all switches except -index (but I did not care of speed):
proc lsort-indices args {
set unsortedList [lindex $args end]
set switches [lrange $args 0 end-1]
set pairs {}
set i -1
foreach el $unsortedList {
lappend pairs [list [incr i] $el]
}
set result {}
foreach el [eval lsort $switches [list -index 1 $pairs]] {
lappend result [lindex $el 0]
}
set result
}Now test it:
% lsort-indices {9 10 11}
1 2 0
% lsort-indices -integer {9 10 11}
0 1 2
%Additional list functions | Arts and crafts of Tcl-Tk programming }

