2

Hi i have an array with basic key-value pair and i want to sort it and then get the keys. The array contents are something like this:

arrVal {
    123adf45ad    ABCD.1
    aldfhr435d    ABCD.9
    lkh45q9er4    ABCD
    1234dartf4    ABCD4
}

So basically my array keys are some kind of encrypted ids and the values are a string values. Since i cannot sort array based on its keys i did something like this:

foreach {key in array..} {
    lappend mylist [$arrVal($key)]; 
}
set mylist [lsort $mylist];

now for the sorted list i want to extract the array keys against those values. I couldn't find any command that can extract the array keys based on its values. Any help?

Puneet Mittal
  • 532
  • 1
  • 15
  • 24

3 Answers3

3

Basically you're almost there. What you want is a reverse map which is not something built into the language (or indeed most languages) but rather a concept: another array with the values of the first array as keys and keys of the first array as values:

array set reverseMap {}
foreach {key val} [array get arrayVal] {
    set reverseMap($val) $key
}

Now you can get the keys like this:

set secondKey $reverseMap([lindex $mylist 1])
slebetman
  • 109,858
  • 19
  • 140
  • 171
  • thanks Slebetman i had that in mind but i thought if there is an easy or short way to do it. Thanks for the help though. :) – Puneet Mittal Jan 03 '13 at 19:00
  • 3
    The only trouble with this technique is if the values are not unique. – glenn jackman Jan 03 '13 at 21:15
  • 2
    You might try: `array set reverseMap [lreverse [array get arrayVal]]` – Donal Fellows Jan 03 '13 at 23:08
  • 1
    @glennjackman: To be fair, what the OP wants to do would be problematic as well if the values are not unique (hint: he wants to get back the key given an array value). Though, with the reverse map, a work-around is to store a list of keys if the value is not unique. – slebetman Jan 04 '13 at 01:14
1

Here's a more step-by-step method:

array set arrVal {
    123adf45ad    ABCD.1
    aldfhr435d    ABCD.9
    lkh45q9er4    ABCD
    1234dartf4    ABCD4
}
set arrValList [list]
foreach {key val} [array get arrVal] {lappend arrValList [list $key $val]}
set sortedKeys [list]
foreach pair [lsort -index 1 $arrValList] {lappend sortedKeys [lindex $pair 0]}
puts $sortedKeys  ;# lkh45q9er4 123adf45ad aldfhr435d 1234dartf4
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0

You can get a list of all the keys in an array with array names.

set mylist [lsort [array names arrVal]]
potrzebie
  • 1,768
  • 1
  • 12
  • 25