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
Related videos on Youtube
Author by
user1228191
Updated on October 16, 2020Comments
-
user1228191 over 3 years
The
INITIAL_ARRAY
isKey -> 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 over 10 yearsThe last line should be replaced by set result [lsort -integer -index 1 $x] since "lsort" produces new list rather than changes existing one.
-
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 whateverlsort
returns.