golang map多维key获取值

有时候需要获取一个interface{}或map[string]interface{}类型的多维map中某个key的值,只能用.(map[string]interface{})慢慢强转换以后来取,key太深的话取起来就麻烦了。因此我写了一个多维map的取值函数,类似于PHP中的多维关联数组。

函数如下:

package main

import (
	"encoding/json"
	"errors"
)

//MapGetValue map[string]interface{}获取值,支持多维
func MapGetValue(keys []string, data interface{}) (interface{}, error) {
	var res interface{}
	var err error
	var copyData interface{}
	var mapData map[string]interface{}

	length := len(keys)

	//检测keys
	if length == 0 {
		return res, errors.New("no key")
	}

	//拷贝data
	copyData, err = Copy(data)

	if err != nil {
		return res, errors.New("map data error")
	}

	//data转换成map
	var ok bool
	if mapData, ok = copyData.(map[string]interface{}); ok == false {
		return res, errors.New("map data format error")
	}

	//keys最后一个index
	lastIndex := len(keys) - 1

	//遍历查找data
	for k, val := range keys {
		if val2, ok2 := mapData[val]; ok2 {
			//到达最后
			if k == lastIndex {
				res = val2
				break
			} else {
				//转成map格式方便下一次循环
				if mapData, ok2 = val2.(map[string]interface{}); ok2 == false {
					err = errors.New("map key count not patch")
					break
				}
			}
		} else {
			err = errors.New("not exists key " + val)
		}
	}

	return res, err
}

//Copy 拷贝
func Copy(a interface{}) (interface{}, error) {
	var d interface{}
	var err error

	//加码
	c, err := json.Marshal(a)

	if err != nil {
		return d, err
	}

	//拷贝
	err = json.Unmarshal(c, &d)

	if err != nil {
		return d, err
	}

	return d, err
}

实例如下:

map的上级和下级元素可以是map[string]interface{}类型,或者其他如map[string]int等等类型。

package main

import (
	"fmt"
)

func main()  {
   var d interface{}

	//示例一(一维)
	d = map[string]string{
		"a": "aaa",
	}

	val, _ := MapGetValue([]string{"a"}, d) //可以不用管error,如果有error,说明不存在或者格式不对

	fmt.Println("示例一取值成功:", val) //输出的值为aaa

	//示例二(多维)
	d = map[string]interface{}{
		"a": map[string]map[string]int{
			"b": map[string]int{
				"c": 333,
			},
		},
	}

	val, _ = MapGetValue([]string{"a", "b", "c"}, d) //可以不用管error,如果error,说明不存在或者格式不对

	fmt.Println("示例二取值成功!", val) //输出的值为333
}

 

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
评论

打赏作者

nakeer

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值