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]
            }
        }
    }
}

原文地址:https://www.cnblogs.com/ExMan/p/11461159.html

时间: 2024-10-26 18:14:55

golang depth read map的相关文章

Golang,用map写个单词统计器

Golang中也有实用的泛型编程模板.如map.据Go官方团队称,其实现为Hash表,而非类似cpp或Java的红黑树.所以理论上速度更能快上几个等级(Hash与红黑树的效率对比可以看我的文章C++中各种<string,T>关联方式的速度对比,效率比约为3:1),但有一些区别,就是遍历时,数据是无需且随机的(当然,后文会讲到有序化的方法).接下来,我们先创建一个map对象. dict:=make(map[string]int); 由于map的强类型,所以一切类型是静态的,map也不例外.从ma

【GoLang笔记】实例分析GoLang built-in数据结构map的赋值引用行为

备注1:本文旨在介绍Go语言中map这个内置数据结构的引用行为,并用实例来说明如何避免这种引用行为带来的"副作用". 备注2:文末列出的参考资料均来自GoLang.org官方文档,需翻墙访问. 1. map internals map是go中内置的数据结构,关于其语法规则,可以查看language specification中这里的说明,或者查看Effective Go中关于Maps的说明,此处略过. map的底层是用hashmap实现的(底层hashmap源码路径为src/pkg/r

Golang教程:Map

什么是 map? Map 是 Go 中的内置类型,它将键与值绑定到一起.可以通过键获取相应的值. 如何创建 map? 可以通过将键和值的类型传递给内置函数 make 来创建一个 map.语法为:make(map[KeyType]ValueType).(译者注:map 的类型表示为 map[KeyType]ValueType)例如: personSalary := make(map[string]int) 上面的代码创建了一个名为 personSalary 的 map.其中键的类型为 string

golang struct转map

struct转map package main import ( "fmt" "reflect" "time" ) type User struct { Id int64 Username string Password string Logintime time.Time } func Struct2Map(obj interface{}) map[string]interface{} { t := reflect.TypeOf(obj) v

golang初学之map

package main import ( "strings" "fmt") // 返回各个单词数量统计的map func WordCount(s string) map[string]int { m := make(map[string] int) for _, word := range strings.Fields(s) { m[word] ++ } return m} func main() { fmt.Println(WordCount("I a

Golang里边的map变量是什么?

结论:是一个指向hmap结构体类型的指针. 首先我们来看一段代码: 输出是true,m是一个指针,fn内部申请的map[int][int]不影响外部m. 所有m是一个指针,那具体m的结构是什么呢?可以通过gdb调试: 所以一切明了,就是一个指针. 原文地址:https://www.cnblogs.com/maji233/p/11071235.html

golang 切片和map查询比较

package main import ( "fmt" "time" ) var testTimeSlice = []string{"aa", "bb", "cc", "dd", "ee", "aa", "zz"} var testTimeMap = map[string]bool{"aa": true, &

Golang:测试map是否存在

请看这个url:http://www.du52.com/text.php?id=561 if v, ok := m1["a"]; ok { fmt.Println(v) } else { fmt.Println("Key Not Found") }

Golang 中使用多维 map

http://tnt.wicast.tk/2015/11/02/golang-multiple-dimension-map/ Golang 的 XML/JSON 解析库乍看使用起来很方便,只要构造一样结构的 Struct 就可以一下子导入到变量中去了.其实手工构造 Struct 非常容易出现结构偏差,而且最要命的是 Unmarshal() 执行的时候不是严格导入所以没有任何报错. 于是这两天写了一个给 Golang 用的 XML to Struct 生成器,希望能一劳永逸. 不过在制作过程中有遇