У меня есть карта массивов карт map[string][]map[string]string, только когда я получаю данные, она имеет формат map[interface{}]map[interface{}][]map[interface{}]interface{}, поэтому мне остается сделать кучу утверждений вложенного типа, что очень неуклюже , занимает много времени на запись, трудно читать / писать и, вероятно, подвержен ошибкам, как это;

        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)
            }
        }

Я искал несколько часов, и я не могу найти более простой способ сделать это, чем код выше.

В любом случае, я могу просто v, ok := setting.(map[string]map[string][]map[string]string) или я просто застрял с кодом выше?

go
0
Zane Hitchcox 17 Авг 2019 в 22:47

2 ответа

Лучший ответ

Это последний код, который я использовал:

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

Он в основном преобразует интерфейсы в map [string] interface {} по одному шагу за раз, что является наилучшим способом сделать это, как я обнаружил, и, по крайней мере, вы остаетесь вне гнездового ада.

Это функция для преобразования в нужные типы:

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
}

В целом, хотя, я думаю, что я просто найду работу вокруг, поэтому мне не нужно делать это вообще.

0
Zane Hitchcox 17 Авг 2019 в 21:41

Вы можете определить структуру с ожидаемой структурой и попытаться разобрать ее с помощью чего-то вроде этого:

https://github.com/mitchellh/mapstructure

Я никогда не пробовал это с map [interface {}] interface {}.

1
Burak Serdar 17 Авг 2019 в 20:15