Динамическое создание вложенных карт в Голанге - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь интерпретировать JSON в Голанге.Я ищу определенный атрибут в неизвестном JSON, ключи которого я знаю, но мой JSON может быть действительно вложенным.Я знаю, сколько «слоев» в моем JSON.

Например, если мой JSON:

nestedJson = { key1: { key2: { key3: "Found data" } } } 

, мои ключи - это ["key1", "key2", "key3 "] и в этом JSON есть 3 слоя, поэтому я могу получить данные обратно, выполнив

var nestedJson = []map[string]map[string]map[string]interface{}
json.Unmarshal([]byte(nestedJon), &nestedJson)
data := nestedJson["key1]["key2"]["key3"]

. Я хочу иметь возможность динамически создавать этот объект nestedJson, указав целочисленное значение дляколичество слоев, которое следует искать.

Может кто-нибудь помочь с этим?Пожалуйста, дайте мне знать, если я не был достаточно ясен!

1 Ответ

0 голосов
/ 26 января 2019

В общем, для подобных случаев вам придется использовать общую способность демаршалинга json.Unmarshal в interface{}.

b := []byte(`{ "key1": { "key2": { "key3": "Found data" } } } `)
var f interface{}
if err := json.Unmarshal(b, &f); err != nil {
    panic(err)
}
fmt.Println(f)

И теперь вы можете использовать группу утверждений типа для исследования f, например, чтобы найти, какие ключи в нем содержатся:

m := f.(map[string]interface{})
for k, v := range m {
    if k == "key3" {
        fmt.Println("found key3. maps to", v)
    }
}

Если вы не нашли ключ 3 на этом уровне, используйте рекурсию для проверки всех значений - они сопоставлены с ключами key3 и т. Д. Что-то вроде

func findNested(m map[string]interface{}, s string) (bool, interface{}) {
    // Try to find key s at this level
    for k, v := range m {
        if k == s {
            return true, v
        }
    }
    // Not found on this level, so try to find it nested
    for _, v := range m {
        nm := v.(map[string]interface{})
        found, val := findNested(nm, s)
        if found {
            return found, val
        }
    }
    // Not found recursively
    return false, nil
}

Примечание: эта функция была быстро взломана и, вероятно, неправильно обрабатывает множество угловых случаев. Это здесь, чтобы продемонстрировать ключевую идею - использовать ее в качестве основы для ваших конкретных потребностей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...