从地图中获取一片钥匙

时间:2014-01-26 11:48:25

标签: go

是否有更简单/更好的方式从Go中的地图获取一片键?

目前,我正在迭代地图并将密钥复制到切片:

i := 0
keys := make([]int, len(mymap))
for k := range mymap {
    keys[i] = k
    i++
}

6 个答案:

答案 0 :(得分:291)

这是一个老问题,但这是我的两分钱。 PeterSO的答案稍微简洁一些,但效率稍差。你已经知道它有多大,所以你甚至不需要使用追加:

keys := make([]int, len(mymap))

i := 0
for k := range mymap {
    keys[i] = k
    i++
}

在大多数情况下,它可能不会产生太大的影响,但是在我的测试中(使用带有1,000,000个随机int64密钥的地图然后生成密钥数组十次)使用每种方法),直接分配数组成员比使用append快20%。

虽然设置容量会消除重新分配,但追加仍然需要做额外的工作来检查你是否已达到每个附加的容量。

答案 1 :(得分:158)

例如,

package main

func main() {
    mymap := make(map[int]string)
    keys := make([]int, 0, len(mymap))
    for k := range mymap {
        keys = append(keys, k)
    }
}

为了提高Go的效率,最小化内存分配非常重要。

答案 2 :(得分:61)

您还可以从包&#34中采用结构[]Value的方法MapKeys获取类型为Value的键数组;反映":

package main

import (
    "fmt"
    "reflect"
)

func main() {
    abc := map[string]int{
        "a": 1,
        "b": 2,
        "c": 3,
    }

    keys := reflect.ValueOf(abc).MapKeys()

    fmt.Println(keys) // [a b c]
}

答案 3 :(得分:9)

更好的方法是使用append

keys = []int{}
for k := range mymap {
    keys = append(keys, k)
}

除此之外,你运气不好 - Go不是一个非常富有表现力的语言。

答案 4 :(得分:4)

我对其他回复中描述的三种方法进行了粗略的基准测试。

显然,在拉动键之前预先分配切片比append快,但是令人惊讶的是,reflect.ValueOf(m).MapKeys()方法比后者慢得多:

❯ go run scratch.go
populating
filling 100000000 slots
done in 56.630774791s
running prealloc
took: 9.989049786s
running append
took: 18.948676741s
running reflect
took: 25.50070649s

代码如下:https://play.golang.org/p/Z8O6a2jyfTH (在操场上运行它会声称它花费的时间太长,因此,可以在本地运行它。)

答案 5 :(得分:0)

访问https://play.golang.org/p/dx6PTtuBXQW

package main

import (
    "fmt"
    "sort"
)

func main() {
    mapEg := map[string]string{"c":"a","a":"c","b":"b"}
    keys := make([]string, 0, len(mapEg))
    for k := range mapEg {
        keys = append(keys, k)
    }
    sort.Strings(keys)
    fmt.Println(keys)
}