When iterating through the returned map in the code, returned by the topic function, the keys are not appearing in order.
How can I get the keys to be in order / sor
If, like me, you find you want essentially the same sorting code in more than one place, or just want to keep the code complexity down, you can abstract away the sorting itself to a separate function, to which you pass the function that does the actual work you want (which would be different at each call site, of course).
Given a map with key type K and value type V, represented as and below, the common sort function might look something like this Go-code template (which Go version 1 does not support as-is):
/* Go apparently doesn't support/allow 'interface{}' as the value (or
/* key) of a map such that any arbitrary type can be substituted at
/* run time, so several of these nearly-identical functions might be
/* needed for different key/value type combinations. */
func sortedMap(m map[], f func(k , v )) {
var keys []
for k, _ := range m {
keys = append(keys, k)
}
sort.Strings(keys) # or sort.Ints(keys), sort.Sort(...), etc., per
for _, k := range keys {
v := m[k]
f(k, v)
}
}
Then call it with the input map and a function (taking (k as its input arguments) that is called over the map elements in sorted-key order.
So, a version of the code in the answer posted by Mingu might look like:
package main
import (
"fmt"
"sort"
)
func sortedMapIntString(m map[int]string, f func(k int, v string)) {
var keys []int
for k, _ := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
f(k, m[k])
}
}
func main() {
// Create a map for processing
m := make(map[int]string)
m[1] = "a"
m[2] = "c"
m[0] = "b"
sortedMapIntString(m,
func(k int, v string) { fmt.Println("Key:", k, "Value:", v) })
}
The sortedMapIntString() function can be re-used for any map[int]string (assuming the same sort order is desired), keeping each use to just two lines of code.
Downsides include:
Other languages have various solutions:
and (to denote types for the key and value) looks a bit familiar, that code template is not terribly unlike C++ templates.range a first-class type such that it could be substituted with a custom ordered-range (in place of range in the original code), I think some other languages provide iterators that are powerful enough to accomplish the same thing.