普通网友 2018-11-05 10:46
浏览 110
已采纳

如何通过map [string] interface {}进行递归迭代

I faced with a problem how to iterate through the map[string]interface{} recursively with additional conditions.

1) if a value is a map - recursively call the method

2) if a value is an array - call method for array

3) if a value isn't a map - process it.

Now when method try to execute doc.throughMap(mv) - error occurs So how can I convert some value to needed type after reflect confirm that value is a map or an array?

type MapType map[string]interface{}
type ArrayType []interface{}
func (doc *Document) throughMap(docMap MapType) MapType {
    for k, v := range docMap {
        vt := reflect.TypeOf(v)
        switch vt.Kind() {
        case reflect.Map:
            if mv, ok := v.(map[string]interface{}); ok {
                docMap[k] = doc.throughMap(mv)
            } else {
                panic("error.")
            }
        case reflect.Array, reflect.Slice:
            if mv, ok := v.([]interface{}); ok {
                docMap[k] = doc.throughArray(mv)
            } else {
                panic("error.")
            }
        default:
            docMap[k] = doc.processType(v)
        }
    }
    return docMap
}

Stacktrace:

panic: error. [recovered]
    panic: error.

goroutine 1 [running]:
encoding/json.(*encodeState).marshal.func1(0xc000074cd0)
    /usr/local/go/src/encoding/json/encode.go:301 +0x9a
panic(0x4bd700, 0x4f9b70)
    /usr/local/go/src/runtime/panic.go:513 +0x1b9
project-name/package/name.(*Document).throughMap(0xc00000c028, 0xc000060180, 0xc00007e000)
    /home/path/to/project/document.go:231 +0x3f4
project-name/package/name.(*Document).convertDocument(0xc00000c028)
    /home/path/to/project/document.go:217 +0x33
project-name/pachage/name.(*Document).MarshalJSON(0xc00000c028, 0x4db740, 0xc00000c028, 0x7f3f0f7540c0, 0xc00000c028, 0xc00001c101)
    /home/path/to/project/document.go:167 +0xd8
encoding/json.marshalerEncoder(0xc00007c000, 0x4db740, 0xc00000c028, 0x16, 0xc000070100)
    /usr/local/go/src/encoding/json/encode.go:453 +0xb7
encoding/json.(*encodeState).reflectValue(0xc00007c000, 0x4db740, 0xc00000c028, 0x16, 0x4c0100)
    /usr/local/go/src/encoding/json/encode.go:333 +0x82
encoding/json.(*encodeState).marshal(0xc00007c000, 0x4db740, 0xc00000c028, 0x4f0100, 0x0, 0x0)
    /usr/local/go/src/encoding/json/encode.go:305 +0xf4
encoding/json.Marshal(0x4db740, 0xc00000c028, 0xc000034698, 0x3, 0x3, 0x4d, 0x0)
    /usr/local/go/src/encoding/json/encode.go:160 +0x52
main.main()
    /home/path/to/project/main.go:21 +0x34d
  • 写回答

2条回答 默认 最新

  • duannian3494 2018-11-05 17:30
    关注

    Use the following code to recurse through maps, arrays and slices of any type:

    func walk(v reflect.Value) {
        fmt.Printf("Visiting %v
    ", v)
        // Indirect through pointers and interfaces
        for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
            v = v.Elem()
        }
        switch v.Kind() {
        case reflect.Array, reflect.Slice:
            for i := 0; i < v.Len(); i++ {
                walk(v.Index(i))
            }
        case reflect.Map:
            for _, k := range v.MapKeys() {
                walk(v.MapIndex(k))
            }
        default:
            // handle other types
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)