2014-10-06 3 views
1

У меня есть случайный JSON (я не знаю схему раньше времени), что я марширую в map[string]interface{}. У меня также есть строка, представляющая значение поля, которое я хотел бы вернуть, что-то вроде "SomeRootKey.NestValue.AnotherNestValue"Доступ к вложенному значению в карте Go

Я хочу, чтобы иметь возможность вернуть это значение. Есть ли простой способ получить доступ к этому значению без каких-либо рекурсивных трюков?

ответ

1

Без рекурсии? да, используя цикл, но нет волшебного способа сделать это.

func getKey(m interface{}, key string) (string, bool) { 
L: 
    for _, k := range strings.Split(key, ".") { 
     var v interface{} 
     switch m := m.(type) { 
     case map[string]interface{}: 
      v = m[k] 
     case []interface{}: 
      idx, err := strconv.Atoi(k) 
      if err != nil || idx > len(m) { 
       break L 
      } 
      v = m[idx] 
     default: 
      break L 
     } 
     switch v := v.(type) { 
     case map[string]interface{}: 
      m = v 
     case []interface{}: 
      m = v 
     case string: 
      return v, true 
     default: 
      break L 
     } 
    } 
    return "", false 
} 

Использование JSON как:

{ 
    "SomeRootKey": { 
     "NestValue": {"AnotherNestValue": "object value"}, 
     "Array": [{"AnotherNestValue": "array value"}] 
    } 
} 

Вы можете использовать:

fmt.Println(getKey(m, "SomeRootKey.NestValue.AnotherNestValue")) 
fmt.Println(getKey(m, "SomeRootKey.Array.0.AnotherNestValue")) 

playground

+0

Это не будет работать с массивами, хотя бы это? Что-то вроде «a.b [0] .val« – K2xL

+0

@ K2xL Я обновил код. – OneOfOne

Смежные вопросы