K2xL
K2xL

Reputation: 10330

Accessing a nested value in a Go map

I have a random JSON (I will not know the schema ahead of time) that I am marshaling into an map[string]interface{}. I also have a string representing the field value I would like to return, something like "SomeRootKey.NestValue.AnotherNestValue"

I want to be able to return that value. Is there an simple way to access that value without doing some recursive tricks?

Upvotes: 2

Views: 190

Answers (1)

OneOfOne
OneOfOne

Reputation: 99371

Without recursion? yes, using a loop, but no there's no magical way to do that.

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
}

Using json like:

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

You can use:

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

playground

Upvotes: 1

Related Questions