如何按顺序遍历Golang中的地图?

时间:2013-08-20 18:47:17

标签: go

请参阅下面的地图

var romanNumeralDict map[int]string = map[int]string{
  1000: "M",
  900 : "CM",
  500 : "D",
  400 : "CD",
  100 : "C",
  90  : "XC",
  50  : "L",
  40  : "XL",
  10  : "X",
  9   : "IX",
  5   : "V",
  4   : "IV",
  1   : "I",
}

我希望按照密钥大小的顺序遍历此地图

  for k, v := range romanNumeralDict {
    fmt.Println("k:", k, "v:", v)
  }

然而,这打印出来

k: 1000 v: M
k: 40 v: XL
k: 5 v: V
k: 4 v: IV
k: 900 v: CM
k: 500 v: D
k: 400 v: CD
k: 100 v: C
k: 90 v: XC
k: 50 v: L
k: 10 v: X
k: 9 v: IX
k: 1 v: I

有没有办法可以按照按键大小的顺序打印出来,所以我想像这样循环浏览这个地图

k:1
K:4
K:5
K:9
k:10

等...

非常感谢你的帮助!

5 个答案:

答案 0 :(得分:44)

收集所有密钥,对其进行排序并按键迭代地图,如下所示:

keys := make([]int, 0)
for k, _ := range romanNumeralDict {
    keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
    fmt.Println(k, romanNumeralDict[k])
}

答案 1 :(得分:9)

你可以通过预先分配keys来加快速度,因为你知道它的长度:

func sortedKeys(m map[Key]Value) ([]Key) {
        keys := make([]Key, len(m))
        i := 0
        for k := range m {
            keys[i] = k
            i++
        }
        sort.Keys(keys)
        return keys
}

KeyValue替换为您的键和值类型(包括sort行)。 咳嗽一般咳嗽

答案 2 :(得分:1)

如果执行速度不是主要问题,则可以使用MapKeys获得排序的键数组。

在此示例中,键的类型为string

keys := reflect.ValueOf(myMap).MapKeys()
keysOrder := func(i, j int) bool { return keys[i].Interface().(string) < keys[j].Interface().(string) }
sort.Slice(keys, keysOrder)

// process map in key-sorted order
for _, key := range keys {
    value := myMap[key.Interface().(string)]
    fmt.Println(key, value)
}
  • 请参阅:Getting a slice of keys from a map
  • 警告:这会绕过一些编译时的类型安全性(如果不是地图,则会发生恐慌)
  • 您需要转换每个键以获得原始值:key.Interface().(string)

答案 3 :(得分:1)

如果您需要的是有序值,则不必使用地图。

您可以使用切片代替:

var romanNumeralDict = []string{
    1000: "M",
    900:  "CM",
    500:  "D",
    400:  "CD",
    100:  "C",
    90:   "XC",
    50:   "L",
    40:   "XL",
    10:   "X",
    9:    "IX",
    5:    "V",
    4:    "IV",
    1:    "I",
}
for k, v := range romanNumeralDict {
    if v == "" {
        continue
    }
    fmt.Println("k:", k, "v:", v)
}

Run on the playground

注意:这段代码需要更多的空间和时间,但您可以看到 Go 标准库代码在许多地方使用了相同的模式。

答案 4 :(得分:0)

您可以通过先明确地对键进行排序来依次遍历地图,然后再通过键遍历地图。由于您从romanNumeralDict开始就知道键的最终大小,因此预先分配所需大小的数组会更有效。

// Slice for specifying the order of the map.
// It is initially empty but has sufficient capacity
// to hold all the keys of the romanNumeralDict map.
keys := make([]int, 0, len(romanNumeralDict))

// Collect keys of the map
i := 0
for k, _ := range romanNumeralDict {
    keys[i] = k
    i++
}

// Ints sorts a slice of ints in increasing order
sort.Ints(keys)

// Iterate over the map by key with an order
for _, k := range keys {
    fmt.Println(k, romanNumeralDict[k])
}