Dictionary 遍历包含不同级别映射的接口映射

Dictionary 遍历包含不同级别映射的接口映射,dictionary,go,interface,range,slice,Dictionary,Go,Interface,Range,Slice,假设我有一张这样的界面图: c := map[string]interface{} { "test": test, "test2": test2, } innerMap1 := make(map[string]interface{}) // map to strings innerMap1["a"] = "String 1" innerMap2 := make(map[string]interface{}) // set mappings, maybe to othe

假设我有一张这样的界面图:

c := map[string]interface{} {
    "test":    test,
    "test2":   test2,
}
innerMap1 := make(map[string]interface{})
// map to strings
innerMap1["a"] = "String 1"
innerMap2 := make(map[string]interface{})
// set mappings, maybe to other types

outerMap := make(map[string]interface{})
outerMap["ABC"] = innerMap1
outerMap["DEF"] = innerMap2
假设
test
map[string]map[string]map[string]string
并且
test2
map[string]string

如何创建一个for循环来枚举映射的每个索引,并通过每个索引的映射进行枚举

到目前为止,我得到了:

func sanitize_map(m map[string]interface{}) map[string]interface{} {
    for k, v := range m {
    //Here is where I want to enumerate through the map of k
    }
    return m
}
您可以使用反射:

import "reflect"

func sanitize_map(m map[string]interface{}) map[string]interface{} {
    for k, v := range m {
        // Do something with the key k
        kind := reflect.ValueOf(v).Kind()
        if kind == reflect.Map {
             // You have to be sure the value is of type map[string]interface{}
             newValue := v.(map[string]interface{})
             // recursively call sanitize
             sanitize_map(newValue)
        }
    }
    return m
}
其特点是:映射中的每个值都必须是nota
map
(atom)或
map[string]接口{}
。注意
map[string]interface{}
map[string]map[string]interface{}
是完全不相关的类型,不能在第一个类型上使用第二个类型的类型断言

但是,您可以将
map[string]map[string]string
放在
map[string]界面{}
中,如下所示:

c := map[string]interface{} {
    "test":    test,
    "test2":   test2,
}
innerMap1 := make(map[string]interface{})
// map to strings
innerMap1["a"] = "String 1"
innerMap2 := make(map[string]interface{})
// set mappings, maybe to other types

outerMap := make(map[string]interface{})
outerMap["ABC"] = innerMap1
outerMap["DEF"] = innerMap2

现在,您可以将outerMap传递给函数,reflect将自动为您“剥离”贴图层。

无需反射;使用a并将值传递回sanitize函数

func sanitizeMap(m map[string]interface{}) map[string]interface{} {
    for k, v := range m {
        _ = k
        if v, ok := v.(map[string]interface{}); ok {
            sanitizeMap(v)
        }
    }
    return m
}

我不太明白你的问题。是否要获取所有映射中所有键的列表、值列表或其他内容?使用reflect会使事情变得更慢,但仍然有一个可能会引起恐慌的类型断言。如果您知道类型,请完全跳过反射。当
v
不是映射时,您的解决方案将在递归结束时失败。对于递归,您总是需要一个终止条件。我看到您使用类型断言失败来结束递归。好的,请记下我最后的评论。我想OP可能想在
v
是原子时做些特别的事情。