按键排序Go地图值

gra*_*nja 84 hashmap go

当迭代主题函数返回的代码中返回的映射时,键不按顺序出现.

如何让键按顺序/排序地图,以便键按顺序排列并且值对应?

这是代码.

Min*_*gyu 138

围棋博客:在行动中去的地图有极好的说明.

当使用范围循环迭代映射时,未指定迭代顺序,并且不保证从一次迭代到下一次迭代是相同的.由于Go 1,运行时随机化地图迭代顺序,因为程序员依赖于先前实现的稳定迭代顺序.如果需要稳定的迭代顺序,则必须维护一个指定该顺序的单独数据结构.

这是我修改后的示例代码版本:http: //play.golang.org/p/dvqcGPYy3-

package main

import (
    "fmt"
    "sort"
)

func main() {
    // To create a map as input
    m := make(map[int]string)
    m[1] = "a"
    m[2] = "c"
    m[0] = "b"

    // To store the keys in slice in sorted order
    var keys []int
    for k := range m {
        keys = append(keys, k)
    }
    sort.Ints(keys)

    // To perform the opertion you want
    for _, k := range keys {
        fmt.Println("Key:", k, "Value:", m[k])
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Key: 0 Value: b
Key: 1 Value: a
Key: 2 Value: c
Run Code Online (Sandbox Code Playgroud)

  • 这可以通过`keys:= make([] int,len(m))`来改进,然后通过索引`keys [i] = k`而不是`append'插入 (34认同)

jos*_*hlf 17

根据Go规范,迭代在地图上的顺序是未定义的,并且可能在程序的运行之间变化.在实践中,它不仅是未定义的,它实际上是故意随机化的.这是因为它过去是可预测的,并且Go语言开发人员不希望人们依赖于未指定的行为,因此他们故意将其随机化,以便依赖此行为是不可能的.

那么,您需要做的是将键拉入切片,对它们进行排序,然后将切片放在切片上,如下所示:

var m map[keyType]valueType
keys := sliceOfKeys(m) // you'll have to implement this
for _, k := range keys {
    v := m[k]
    // k is the key and v is the value; do your computation here
}
Run Code Online (Sandbox Code Playgroud)


Ina*_*mus 9

现在,这里的所有答案都包含地图的旧行为。在Go 1.12+中,您只需打印一个地图值,它将自动按键排序。之所以添加它,是因为它可以轻松测试地图值。

func main() {
    m := map[int]int{3: 5, 2: 4, 1: 3}
    fmt.Println(m)

    // In Go 1.12+
    // Output: map[1:3 2:4 3:5]

    // Before Go 1.12 (the order was undefined)
    // map[3:5 2:4 1:3]
}
Run Code Online (Sandbox Code Playgroud)

现在可以按键排序的顺序打印地图,以简化测试。排序规则是:

  • 适用时,nil比较低
  • 整数,浮点数和字符串按<
  • NaN比非NaN浮点数少
  • 布尔比较假之前为真
  • 复杂比较真实,然后虚构
  • 指针按机器地址比较
  • 通道值按机器地址比较
  • 结构依次比较每个字段
  • 数组依次比较每个元素
  • 接口值首先通过描述具体类型的reflect.Type进行比较,然后再按照先前规则中的具体值进行比较。

打印地图时,非自反键值(如NaN)以前显示为<nil>。从此版本开始,将打印正确的值。

在这里阅读更多

  • 这似乎仅适用于fmt打包和打印。问题问如何对地图排序,而不是如何打印排序的地图? (2认同)