4
votes

In short: How do I traverse a map in sorted key order, regardless of the map's type?

I found a few related questions, the closest one suggesting that it can't be done without relying on the reflect module. Is this understanding correct?

Consider this Go code, which traverses two maps of different types, in sorted order of their keys:

mapOne := map[int]string {
    1: "a",
    2: "b",
    3: "c",
}
keysOne := make([]int, 0, len(mapOne))
for key, _ := range mapOne {
    keysOne = append(keysOne, key)
}
sort.Ints(keysOne)
for _, key := range keysOne {
    value := mapOne[key]
    fmt.Println(key, value)
}

mapTwo := map[string]int {
    "a": 1,
    "b": 2,
    "c": 3,
}
keysTwo := make([]string, 0, len(mapTwo))
for key, _ := range mapTwo {
    keysTwo = append(keysTwo, key)
}
sort.Strings(keysTwo)
for _, key := range keysTwo {
    value := mapTwo[key]
    fmt.Println(key, value)
}

The logic to extract the keys and then sort them is duplicated for the two different map types. Is there any way to factor out this logic and avoid duplication?

I got stuck trying to write an interface to provide a SortedKeys method. In particular, the return type of SortedKeys depends on the type of the map, and I can't figure out how to express that in Go.

1

1 Answers

2
votes

I think whoever told you you'd need reflect was correct; that's probably overkill though. I think the duplication is acceptable here.

(alternatively, you could implement your own map that uses some kind of interface for keys, but you'd still end up needing to make a type that satisfies the interface for each underlying key type)