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 ...
随机推荐
- mysqldump 使用--tab=path参数时提示mysqldump: Got error: 1290: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement when executing 'SELECT INTO OUTFILE'
报错: [root@zedu test]# mysqldump -h127.0.0.1 -uroot -p --single-transaction --add-drop-database --tab ...
- five rendering ideas 里获取csm的 shadow边界做 pcf
http://advances.realtimerendering.com/s2011/White,%20BarreBrisebois-%20Rendering%20in%20BF3%20(Siggr ...
- select * from a,b探讨
select * from a,b探讨 今天看同事代码里使用了select * from a,b where a.id=b.id,而我平时都是使用select * from a inner join ...
- Eclipse 的 CheckStyle 插件
Eclipse 的 CheckStyle 插件 1.简介 Checkstyle 是 SourceForge 下的一个开源项目,提供了一个帮助 JAVA 开发人员遵守某些编码规范的工具.它能进行自动化代 ...
- 如何制作纯净的U盘启动盘
1.去下载**WinPE工具箱**U盘启动盘制作工具 下载地址:http://www.wepe.com.cn/download.html
- ASCII和UTF-8
造冰箱的熊猫@cnblogs 2018/12/11 用了这么久的UTF-8,第一次了解了点UTF-8的细节 UTF-8[1]属于变长度编码.一个UTF-8字符的编码长度为1~4个字节. 1)长度为1个 ...
- MessagePack Java Jackson 在不关闭输出流(output stream)的情况下序列化多变量
com.fasterxml.jackson.databind.ObjectMapper 在默认的情况下在写出输入后将会关闭输出流(output stream). 如果你希望序列化多值变量在同一个输出流 ...
- luoguP3373 【模板】线段树 2
P3373 [模板]线段树 2 969通过 3.9K提交 题目提供者 HansBug 标签 云端↑ 难度 提高+/省选- 时空限制 1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两 ...
- Visualizing and Understanding Convolutional Networks
前言:研究卷积神经网络,把阅读到的一些文献经典的部分翻译一下,写成博客,代码后续给出,不足之处还请大家指出. 本文来自:tony-tan.com Github:github.com/Tony-Tan ...
- 2016 ICPC 大连网络赛 部分题解
先讲1007,有m个人,n种石头,将n种石头分给m个人,每两个人之间要么是朋友关系,要么是敌人关系,朋友的话他们必须有一种相同颜色的石头,敌人的话他们必须所有石头的颜色都不相同.另外,一个人可以不拥有 ...