如果我有一张地图m,那么有更好的方法可以获得值的切片
package main
import (
"fmt"
)
func main() {
m := make(map[int]string)
m[1] = "a"
m[2] = "b"
m[3] = "c"
m[4] = "d"
// Can this be done better?
v := make([]string, len(m), len(m))
idx := 0
for _, value := range m {
v[idx] = value
idx++
}
fmt.Println(v)
}
Run Code Online (Sandbox Code Playgroud)
是否有地图的内置功能?Go包中是否有一个函数,或者这是我必须做的最佳代码?
bla*_*een 71
您可以maps.Values从golang.org/x/exp包装中使用。
Values 返回映射 m 的值。这些值的顺序不确定。
func main() {
m := map[int]string{1: "a", 2: "b", 3: "c", 4: "d"}
v := maps.Values(m)
fmt.Println(v)
}
Run Code Online (Sandbox Code Playgroud)
该软件包exp包含实验代码。签名将来可能会也可能不会改变,并且可能会也可能不会升级到标准库。
如果您不想依赖实验包,您可以轻松地自己实现它。事实上,以下代码片段是从exp/maps包中复制粘贴的,最初由Ian Lance Taylor编写:
func Values[M ~map[K]V, K comparable, V any](m M) []V {
r := make([]V, 0, len(m))
for _, v := range m {
r = append(r, v)
}
return r
}
Run Code Online (Sandbox Code Playgroud)
jim*_*imt 50
很不幸的是,不行.没有内置的方法来做到这一点.
作为旁注,您可以在切片创建中省略capacity参数:
v := make([]string, len(m))
Run Code Online (Sandbox Code Playgroud)
容量与此处的长度相同.
nem*_*emo 46
作为jimt帖子的补充:
您也可以使用append而不是显式地将值分配给它们的索引:
m := make(map[int]string)
m[1] = "a"
m[2] = "b"
m[3] = "c"
m[4] = "d"
v := make([]string, 0, len(m))
for _, value := range m {
v = append(v, value)
}
Run Code Online (Sandbox Code Playgroud)
请注意,长度为零(尚未存在元素),但容量(已分配空间)使用元素数初始化m.这样做,因此append每次切片的容量v用完时都不需要分配内存.
你也可以make没有容量值的切片,让我们append为自己分配内存.
不一定更好,但更简洁的方法是定义Slice LENGTH 和 CAPACITY,例如txs := make([]Tx, 0, len(txMap))
// Defines the Slice capacity to match the Map elements count
txs := make([]Tx, 0, len(txMap))
for _, tx := range txMap {
txs = append(txs, tx)
}
Run Code Online (Sandbox Code Playgroud)
完整示例:
package main
import (
"github.com/davecgh/go-spew/spew"
)
type Tx struct {
from string
to string
value uint64
}
func main() {
// Extra touch pre-defining the Map length to avoid reallocation
txMap := make(map[string]Tx, 3)
txMap["tx1"] = Tx{"andrej", "babayaga", 10}
txMap["tx2"] = Tx{"andrej", "babayaga", 20}
txMap["tx3"] = Tx{"andrej", "babayaga", 30}
txSlice := getTXsAsSlice(txMap)
spew.Dump(txSlice)
}
func getTXsAsSlice(txMap map[string]Tx) []Tx {
// Defines the Slice capacity to match the Map elements count
txs := make([]Tx, 0, len(txMap))
for _, tx := range txMap {
txs = append(txs, tx)
}
return txs
}
Run Code Online (Sandbox Code Playgroud)
简单的解决方案,但有很多问题。阅读这篇博文了解更多详情:https : //web3.coach/golang-how-to-convert-map-to-slice-three-gotchas
| 归档时间: |
|
| 查看次数: |
69205 次 |
| 最近记录: |