遍历一个包含不同层级的映射的接口的地图。

huangapple go评论92阅读模式
英文:

Iterate through a map of interface that contains different levels of maps

问题

假设我有一个如下所示的接口映射:

c := map[string]interface{}{
    "test":  test,
    "test2": test2,
}

假设testmap[string]map[string]map[string]string类型,test2map[string]string类型。

我想创建一个循环,可以枚举每个映射的索引,并且还可以枚举每个索引的映射。目前我已经得到了以下代码:

func sanitize_map(m map[string]interface{}) map[string]interface{} {
    for k, v := range m {
        // 这里是我想要枚举 k 的映射的地方
    }
    return m
}

请注意,这只是一个示例代码,具体的实现取决于你想要做什么操作。你可以在// 这里是我想要枚举 k 的映射的地方的位置编写你想要执行的代码,以枚举k的映射。

英文:

So lets say I have a map of interface like this:

c := map[string]interface{} {
    "test":    test,
    "test2":   test2,
}

Assuming that test is a map[string]map[string]map[string]string and test2 is map[string]string.

How would I create a for loop that would enumerate each index of the map and would enumerate through each index's map also?

So far I have gotten:

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
}

答案1

得分: 4

不需要使用反射;使用类型断言并将值传回到你的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
}

在你的sanitize函数中,使用类型断言将值v断言为map[string]interface{}类型,如果断言成功,则递归调用sanitizeMap函数。最后返回map m。

英文:

No need for reflection; use a type assertion and pass the value back to your sanitize function

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
}

答案2

得分: 0

你可以使用反射(reflect)来实现:

import "reflect"

func sanitize_map(m map[string]interface{}) map[string]interface{} {
    for k, v := range m {
        // 对键 k 进行处理
        kind := reflect.ValueOf(v).Kind()
        if kind == reflect.Map {
             // 你必须确保值的类型是 map[string]interface{}
             newValue := v.(map[string]interface{})
             // 递归调用 sanitize_map
             sanitize_map(newValue)
        }
    }
    return m
}

需要注意的是:map 中的每个值必须是一个非 map 类型(原子类型)或者是 map[string]interface{} 类型。注意 map[string]interface{}map[string]map[string]interface{} 是完全不相关的类型,你不能将第二种类型的断言应用于第一种类型。

然而,你可以将 map[string]map[string]string 放入 map[string]interface{} 中,像这样:

innerMap1 := make(map[string]interface{})
// 映射到字符串
innerMap1["a"] = "String 1"
innerMap2 := make(map[string]interface{})
// 设置映射,可能是其他类型

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

现在你可以将 outerMap 传递给函数,反射会自动为你“剥离”多层嵌套的 map。

英文:

You can use reflect:

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
}

The carveat is: every value in the map has to be either not a map (atom) or a map[string]interface{}. Note map[string]interface{} and map[string]map[string]interface{} are completely unrelated types, and you cannot use a type assertion of the second type on the first one.

However, you can put a map[string]map[string]string in a map[string]interface{}, like this:

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

Now you can pass outerMap to the function, and reflect will automatically "strip" the layers of maps for you.

huangapple
  • 本文由 发表于 2015年9月16日 22:42:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/32611829.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定