在Go中是否有更简单/更好的方法从地图中获取键片?
目前我在地图上迭代并复制键到一个切片:
i := 0
keys := make([]int, len(mymap))
for k := range mymap {
keys[i] = k
i++
}
在Go中是否有更简单/更好的方法从地图中获取键片?
目前我在地图上迭代并复制键到一个切片:
i := 0
keys := make([]int, len(mymap))
for k := range mymap {
keys[i] = k
i++
}
当前回答
例如,
package main
func main() {
mymap := make(map[int]string)
keys := make([]int, 0, len(mymap))
for k := range mymap {
keys = append(keys, k)
}
}
为了提高Go的效率,最小化内存分配是很重要的。
其他回答
Go现在有泛型了。你可以用maps.Keys获取任何地图的钥匙。
使用示例:
intMap := map[int]int{1: 1, 2: 2}
intKeys := maps.Keys(intMap)
// intKeys is []int
fmt.Println(intKeys)
strMap := map[string]int{"alpha": 1, "bravo": 2}
strKeys := maps.Keys(strMap)
// strKeys is []string
fmt.Println(strKeys)
地图包可以在golang.org/x/exp/maps找到。这是实验性的,在Go兼容性保证之外。他们的目标是在未来的Go 1.19中将其移到std库中。
操场上:https://go.dev/play/p/fkm9PrJYTly
对于那些不喜欢导入exp包的人,你可以复制源代码:
// Keys returns the keys of the map m.
// The keys will be an indeterminate order.
func Keys[M ~map[K]V, K comparable, V any](m M) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}
访问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)
}
一个更好的方法是使用append:
keys = []int{}
for k := range mymap {
keys = append(keys, k)
}
除此之外,你就不走运了——围棋不是一种很有表现力的语言。
例如,
package main
func main() {
mymap := make(map[int]string)
keys := make([]int, 0, len(mymap))
for k := range mymap {
keys = append(keys, k)
}
}
为了提高Go的效率,最小化内存分配是很重要的。
我对其他回答中描述的三种方法做了一个粗略的基准。
显然,在提取键之前预分配切片比追加快,但令人惊讶的是,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 (在操场上运行它会中止,因为它花费的时间太长,所以,在本地运行它。)