英文:
Iterate through a map of interface that contains different levels of maps
问题
假设我有一个如下所示的接口映射:
c := map[string]interface{}{
"test": test,
"test2": test2,
}
假设test
是map[string]map[string]map[string]string
类型,test2
是map[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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论