golang depth read map
Foreword: I optimized and improved the below solution, and released it as a library here: github.com/icza/dyno
.
The cleanest way would be to create predefined types (structures struct
) that model your JSON, and unmarshal to a value of that type, and you can simply refer to elements using Selectors (for struct
types) and Index expressions (for maps and slices).
However if your input is not of a predefined structure, I suggest you the following 2 helper functions: get()
and set()
. The first one accesses (returns) an arbitrary element specified by an arbitrary path (list of string
map keys and/or int
slice indices), the second changes (sets) the value specified by an arbitrary path (implementations of these helper functions are at the end of the answer).
You only have to include these 2 functions once in your project/app.
And now using these helpers, the tasks you want to do becomes this simple (just like the python solution):
fmt.Println(get(d, "key3", 0, "c2key1", "c3key1"))
set("NEWVALUE", d, "key3", 0, "c2key1", "c3key1")
fmt.Println(get(d, "key3", 0, "c2key1", "c3key1"))
Output:
change1
NEWVALUE
Try your modified app on the Go Playground.
Note - Further Simplification:
You can even save the path in a variable and reuse it to simplify the above code further:
path := []interface{}{"key3", 0, "c2key1", "c3key1"}
fmt.Println(get(d, path...))
set("NEWVALUE", d, path...)
fmt.Println(get(d, path...))
And the implementations of get()
and set()
are below. Note: checks whether the path is valid is omitted. This implementation uses Type switches:
func get(m interface{}, path ...interface{}) interface{} {
for _, p := range path {
switch idx := p.(type) {
case string:
m = m.(map[string]interface{})[idx]
case int:
m = m.([]interface{})[idx]
}
}
return m
}
func set(v interface{}, m interface{}, path ...interface{}) {
for i, p := range path {
last := i == len(path)-1
switch idx := p.(type) {
case string:
if last {
m.(map[string]interface{})[idx] = v
} else {
m = m.(map[string]interface{})[idx]
}
case int:
if last {
m.([]interface{})[idx] = v
} else {
m = m.([]interface{})[idx]
}
}
}
}
golang depth read map的更多相关文章
- 记一次坑爹的golang 二维map判断问题
记一次坑爹的golang 二维map判断问题 2018年10月18日 23:16:21 yinnnnnnn 阅读数:32更多 个人分类: golang 版权声明:本文为博主原创文章,未经博主允许不 ...
- Golang基础教程——map使用篇
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第7篇文章,我们来聊聊golang当中map的用法. map这个数据结构我们经常使用,存储的是key-value的键 ...
- Golang,用map写个单词统计器
Golang中也有实用的泛型编程模板.如map.据Go官方团队称,其实现为Hash表,而非类似cpp或Java的红黑树.所以理论上速度更能快上几个等级(Hash与红黑树的效率对比可以看我的文章C++中 ...
- Golang 入门 : 映射(map)
映射是一种数据结构,用于存储一系列无序的键值对,它基于键来存储值.映射的特点是能够基于键快速检索数据.键就像是数组的索引一样,指向与键关联的值.与 C++.Java 等编程语言不同,在 Golang ...
- Golang教程:Map
什么是 map? Map 是 Go 中的内置类型,它将键与值绑定到一起.可以通过键获取相应的值. 如何创建 map? 可以通过将键和值的类型传递给内置函数 make 来创建一个 map.语法为:mak ...
- golang struct 转map 及 map[string]*Struct 初始化和遍历
package main import ( "encoding/json" "errors" "fmt" "reflect&quo ...
- 深入理解golang:sync.map
疑惑开篇 有了map为什么还要搞个sync.map 呢?它们之间有什么区别? 答:重要的一点是,map并发不是安全的. 在Go 1.6之前, 内置的map类型是部分goroutine安全的,并发的读没 ...
- golang struct转map
struct转map package main import ( "fmt" "reflect" "time" ) type User st ...
- golang中,map作为函数参数是如何传递的
当你声明一个map的时候: m := make(map[int]int) 编译器会调用 runtime.makemap: // makemap implements a Go map creation ...
随机推荐
- java HttpClientUtil帮助类
自己写的java模拟请求帮助类,已经包含header头构造,会话session维持 package com.haozl.back.util; import java.io.File; import j ...
- kubernetes(K8S)快速安装与配置集群搭建图文教程
kubernetes(K8S)快速安装与配置集群搭建图文教程 作者: admin 分类: K8S 发布时间: 2018-09-16 12:20 Kubernetes是什么? 首先,它是一个全新的基于容 ...
- BZOJ4777 [Usaco2017 Open]Switch Grass[最小生成树+权值线段树套平衡树]
标题解法是吓人的. 图上修改询问,不好用数据结构操作.尝试转化为树来维护.发现(不要问怎么发现的)最小生成树在这里比较行得通,因为最近异色点对一定是相邻的(很好想),所以只要看最短的一条两端连着异色点 ...
- redis主从配置及其java的调用(转)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/gsying1474/article/de ...
- [Algorithm] Area of polygon
How to calculate the area of polygon. For a triangle like: We can calculate the area: function cross ...
- 【Python网络】子网划分
ip地址的结构和分类 根据 TCP/IP 协议,连接在internet上的每个设备都必须有一个ip地址 他是一个32位二进制数,也可以用点分十进制表示,每八位一组,用一个十进制表示即0-255,每组用 ...
- Qbxt AH d4 && day-6
/* 这两天考试直接呵呵了. 赶脚对qbxt的题目无感. 同时也发现了自己的一些问题. 一些思路题总是自己傻逼的挖个坑跳进去. 这两天场场倒数ORZ. 始终是最弱的.... 然后NOIP光荣三等奖了吧 ...
- fhq Treap(无旋Treap)
先吹一波fhq dalao,竟然和我一个姓,我真是给他丢脸. 昨天treap就搞了一下午,感觉自己弱爆了.然后今天上午又看了一个上午的无旋treap再次懵逼,我太弱了,orzorz. 所以写个博客防止 ...
- JavaWeb_(Hibernate框架)使用Hibernate开发用户注册功能
使用Hibernate开发用户注册功能: 用户在register.jsp表单成功后,页面跳转到login.html,数据库中会存放用户注册的信息 <%@ page language=" ...
- C++入门经典-例7.7-对象与复制,菌类的繁殖
1:当函数以相应的类作为形参列表时,对象可以作为函数的参数传入.在学习函数时,我们曾提过,值传递先复制实参产生副本.那么对象的副本是怎样的呢? 复制构造函数是指类的对象被复制时所调用的函数.下面两种情 ...