Go map 转 slice
Posted 恋喵大鲤鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go map 转 slice相关的知识,希望对你有一定的参考价值。
编码中,我们可能需要将 map 的 key 或者 value 转换为 slice 进行操作。
面对具体类型 map 如 map[string]string,我们很容易写出下面的转换函数。
// Map2StrSlice converts the key and value of map to string slice
func Map2StrSlice(m map[string]string)([]string, []string) {
slK, slV := make([]string, 0, len(m)), make([]string, 0, len(m))
for k, v := {
slK = append(slK, k)
slV = append(slV, v)
}
return slK, slV
}
实现简单,满足了我们对类型为 map[string]string 的转换。
但是面对其他类型的 map,比如 map[stirng]int,map[stirng]uint,map[stirng]bool…,按照上面的思路,每一个 map 类型都要实现一个转换函数,代码非常冗余。
实际上,可以借助 go reflect 反射能力和开源转换库 cast,写出一个支持泛型的转换函数。
// Map2SliceE converts keys and values of map to slice with error
func Map2SliceE(i interface{})([]interface{}, []interface{}, error) {
kind := reflect.TypeOf(i).Kind()
if kind != reflect.Map {
return nil, nil, errors.New("the input is not a map")
}
m := reflect.ValueOf(i)
keys := m.MapKeys()
slK, slV := make([]interface{}, 0, len(keys)), make([]interface{}, 0, len(keys))
for _, k := range keys {
slK = append(slK, k.Interface())
v := m.MapIndex(k)
slV = append(slV, v.Interface())
}
return slK, slV, nil
}
// Map2StrSliceE converts keys and values of map to string slice with error
func Map2StrSliceE(i interface{})([]string, []string, error) {
slK, slV, err := Map2SliceE(i)
if err != nil {
return nil, nil, err
}
k, err := cast.ToStringSliceE(slK)
if err != nil {
return nil, nil, err
}
v, err := cast.ToStringSliceE(slV)
if err != nil {
return nil, nil, err
}
return k, v, nil
}
转换示例:
package main
import (
"errors"
"fmt"
"reflect"
"github.com/spf13/cast"
)
func main() {
m0 := map[string]string{"CN": "China", "HK": "Hong Kong", "AU": "Australia"}
m1 := map[string]int{"CN":86, "HK":852,"AU":61}
m2 := map[int]string{86:"China", 852:"Hong Kong",61:"Australia"}
k0, v0, e0 := Map2StrSliceE(m0)
k1, v1, e1 := Map2StrSliceE(m1)
k2, v2, e2 := Map2StrSliceE(m2)
fmt.Println(k0, v0, e0)
fmt.Println(k1, v1, e1)
fmt.Println(k2, v2, e2)
}
运行输出:
[CN HK AU] [China Hong Kong Australia] <nil>
[AU CN HK] [61 86 852] <nil>
[86 852 61] [China Hong Kong Australia] <nil>
注意:map 的遍历顺序是随机的,所以每次输出的结果可能不同。
为了方便调用,可以封一个不返回错误的版本。
// Map2StrSlice converts keys and values of map to string slice
func Map2StrSlice(i interface{})([]string, []string) {
slK, slV, _ := Map2StrSliceE(i)
return slK, slV
}
以上函数已开源至 GitHub 工具库 go-huge-util,可直接通过 go mod 方式 import 然后使用。
package main
import (
"fmt"
"github.com/dablelv/go-huge-util"
)
func main() {
m := map[string]string{"CN": "China", "HK": "Hong Kong", "AU": "Australia"}
fmt.Println(util.Map2StrSlice(m))
}
运行输出
[CN HK AU] [China Hong Kong Australia]
参考文献
[1] GitHub go-huge-util
[2] segmentfault.go语言,如何把map转为slice?
以上是关于Go map 转 slice的主要内容,如果未能解决你的问题,请参考以下文章
[GO专栏-5]GO中5 分组声明与array, slice, map