前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go map 转 slice

Go map 转 slice

作者头像
恋喵大鲤鱼
发布2021-07-14 15:24:21
2.2K0
发布2021-07-14 15:24:21
举报
文章被收录于专栏:C/C++基础C/C++基础
在这里插入图片描述
在这里插入图片描述

编码中,我们可能需要将 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?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-07-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档