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 ...
随机推荐
- gluOrtho2D与glViewport
https://blog.csdn.net/HouraisanF/article/details/83444183 窗口与显示主要与三个量有关:世界坐标,窗口大小和视口大小.围绕这些量共有4个函数: ...
- Hadoop-No.7之行键
和哈希表类比,HBase中的行键类似于哈希表中的键.要构造一个良好的HBase模式,关键之一就是选择一个合适的行键. 1 记录检索 行键是HBase中检索记录所使用的键.HBase记录含有的列在数量上 ...
- Mybatis 向oracle批量插入与更新数据
插入 <insert id="batchSave" parameterType="java.util.List"> INSERT INTO T_UP ...
- 部署flask到阿里云服务器ECS
比较难的一点是:部署到云服务器上之后,通过公网没法访问. 这就要说回道 本地开发时的一个小细节:通过http://127.0.0.1:5000是可以访问的,但通过http://[本地ip]:5000是 ...
- IO—转换流和键盘录入
简单来说,由于方法的局限性和功能的需要,特此产生了转换流. InputStreamReader是字节流转换字符流的桥梁,为了提高效率,可以在缓冲区中放入转化流的对象,,并且构造函数第二个参数可以传入一 ...
- 【leetcode】1286. Iterator for Combination
题目如下: Design an Iterator class, which has: A constructor that takes a string characters of sorted di ...
- 如何利用fiddler4 抓取手机的数据包
1.安装fiddler . 2.设置fiddler .tool==> option里面 https 要打开,然后选择actions 第一个 安装本地证书: 3.设置手机访问的数据都要经过fi ...
- XMl特殊字符转换参考
参考链接:https://blog.csdn.net/goon_star/article/details/49636505 处理SVG Text元素不能正确显示特殊字符 特殊符号 命名实体 十进制编码 ...
- C/C++ - malloc/free和new/delete的区分
new/delete与malloc/free的区别主要表现在以下几个方面: 注意:最主要的区别,new/delete是运算符,而malloc/free是函数 (1).new能够自动计算需要分配的内存空 ...
- vue整合adminLTE
前端框架AdminLTE 中文教程 如何用vue整合adminlte模板 1.adminlte 下载地址 : https://github.com/almasaeed2010/AdminLTE/rel ...