How can I sort a TCL array based on the values of its keys?

28,662

Solution 1

Starting with Tcl 8.6, you could do

lsort -stride 2 -integer [array get a]

which would produce a flat list of key/value pairs sorted on values.

Before lsort gained the -stride option, you had to resort to constructing a list of lists out of the flat list array get returns and then sort it using the -index option for lsort:

set x [list]
foreach {k v} [array get a] {
    lappend x [list $k $v]
}
lsort -integer -index 1 $x

Solution 2

The previous methods on this didn't work for me, when I have an array:

[array get a] == D 1 E 3 A 5 B 8 C 10

I do a the following and receive the error:

lsort -stride 2 -integer [array get a]

expected integer but got "D"

You need to also add in an index:

lsort -integer -stride 2 -index 1 [array get a]

D 1 C 10 E 3 A 5 B 8

And then you can change the direction:

lsort -decreasing -integer -stride 2 -index 1 [array get a]

C 10 B 8 A 5 E 3 D 1

Which then gives the correct answer

Share:
28,662

Related videos on Youtube

user1228191
Author by

user1228191

Updated on October 16, 2020

Comments

  • user1228191
    user1228191 over 3 years

    The INITIAL_ARRAY is

    Key -> Value
    B      8
    C     10
    A      5
    E      3
    D      1
    

    To get a sorted array based on key, I use

    set sorted_keys_array [lsort [array names INITIAL_ARRAY]]
    

    to get the output

    Key -> Value
    A     5
    B     8
    C     10
    D     1
    E     3
    

    Like wise, how to get a sorted tcl array based on values of keys, like output below?

    Key -> Value
     C     10
     B     8 
     A     5
     E     3
     D     1
    
  • mkostya
    mkostya over 10 years
    The last line should be replaced by set result [lsort -integer -index 1 $x] since "lsort" produces new list rather than changes existing one.
  • kostix
    kostix over 10 years
    @mkostya, I demonstrated the idea, not a complete program. Moreover, there are legitimate cases to just use the return value of a command without assigning it to a variable -- for instance, you could wrap a proc body around the second example, and that proc would return whatever lsort returns.

Related