如何将嵌套接口转换为地图切片的地图?

I have a map of arrays of maps map[string][]map[string]string, only, when I get the data, it's in the format map[interface{}]map[interface{}][]map[interface{}]interface{}, so I'm left to do a bunch of nested type assertions, which is really clunky, takes a long time to write, is hard to read/write, and is probably error prone, like this;

        if key == "identities" {
            idErrMessage := "Sorry, there was a problem with an identity"
            idArray, ok := setting.(map[string]interface{})
            if ok {
                for idType, ids := range idArray {
                    idGroupArray, ok := ids.([]interface{})
                    if ok {
                        for _, idGroup := range idGroupArray {
                            id, ok := idGroup.(map[interface{}]interface{})
                            if ok {
                                log.Println("type:", idType)
                                for key, val := range id {
                                    log.Printf("%v: %v", key, val)
                                }
                            } else {
                                log.Fatal(idErrMessage)
                            }
                        }
                    } else {
                        log.Fatal(idErrMessage)
                    }
                }
            } else {
                log.Fatal(idErrMessage)
            }
        }

I've been searching for a few hours now, and I can't seem to find an easier way to do this than the code above.

Is there anyway I can just v, ok := setting.(map[string]map[string][]map[string]string), or am I just stuck with the code above?

This is the final code I used:

if key == "identities" {
    idTypes := convertToStringMap(setting)
    ghIds := convertToMapSlice(idTypes["github"])
    for _, ghId := range ghIds {
        for key, value := range convertToStringMap(ghId) {
            log.Println(key, value)
        }
    }
}

it basically converts the interfaces to map[string]interface{} one step at a time, which is the best way to do it I've found, and at least you stay out of nesting hell.

These are the function to convert to the proper types:

func convertToStringMap(i interface{}) map[string]interface{} {
    v, ok := i.(map[string]interface{})
    if !ok {
        v, ok := i.(map[interface{}]interface{})
        if ok {
            m2 := map[string]interface{}{}
            for k, v := range v {
                m2[k.(string)] = v
            }
            return m2
        } else {
            log.Fatal("There was a problem converting to a string map")
        }
    }
    return v
}

func convertToMapSlice(i interface{}) []interface{} {
    v, ok := i.([]interface{})
    if !ok {
        log.Fatal("There was a problem converting to a slice")
    }
    return v
}

Overall though, I think I'm just going to find a work around so I don't have to do this at all.

You can define a struct with the expected structure, and try to unmarshal to it with something like this:

https://github.com/mitchellh/mapstructure

I never tried it with map[interface{}]interface{} though.