4

I was wondering if there is an elegant way of sorting dict by value in Tcl.

Suppose I have a following dict:

set d1 [dict create k1 10 k2 89 k3 1 k4 15 k5 20]
# Results in dict of form
# k1 => 10
# k2 => 89
# k3 => 1
# k4 => 15
# k5 => 20

Now I want to sort this dictionary so that I have:

# k3 => 1
# k1 => 10
# k4 => 15
# k5 => 20
# k2 => 89

I was hoping there is something similar to Python's sorted().

Malcolm32
  • 41
  • 1
  • 2

1 Answers1

14

There is, if you have Tcl 8.6 (this uses the fact that dictionaries can be converted cheaply to and from lists):

set sorted [lsort -integer -stride 2 -index 1 $d1]

If you're still on 8.5 (likely; 8.6 is still in beta) then you need to use several steps:

proc sortDictByValue {dict args} {
    set lst {}
    dict for {k v} $dict {lappend lst [list $k $v]}
    return [concat {*}[lsort -index 1 {*}$args $lst]]
}
set sorted [sortDictByValue $d1]

The -stride option is easier to use, if you've got it.

Community
  • 1
  • 1
Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • 1
    Thanks! And -stride option of lsort in 8.6 looks really useful. – Malcolm32 Apr 20 '11 at 08:17
  • 2
    Comment by anonymous user: I think `-integer` should be added, else the values are sorted in dictionary order. For example: `set sorted [lsort -integer -stride 2 -index 1 $d1]`. – Anne Dec 26 '11 at 18:28
  • 1
    @Anne: That's constraining the meaning of “sorted”; the questioner was not very precise in what they meant. – Donal Fellows Dec 31 '11 at 17:34