Skip to content

Instantly share code, notes, and snippets.

@lxe
Created May 3, 2017 00:02
Show Gist options
  • Save lxe/6caaf1054d4452b1b9f20ff01d487008 to your computer and use it in GitHub Desktop.
Save lxe/6caaf1054d4452b1b9f20ff01d487008 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"errors"
"fmt"
"reflect"
"strconv"
)
func get(o interface{}, path []string) (interface{}, error) {
if len(path) <= 0 {
return o, nil
}
t := reflect.TypeOf(o)
p, rest := path[0], path[1:]
switch t.Kind() {
case reflect.Map:
r, ok := o.(map[string]interface{})[p]
if !ok || r == nil {
return nil, errors.New("key " + p + " does not exist")
}
return get(r, rest)
case reflect.Slice:
r := o.([]interface{})
l, err := strconv.Atoi(p)
if err != nil {
return nil, err
}
if l >= len(r) {
return nil, errors.New("index " + p + " is out of bounds")
}
return get(r[l], rest)
}
return nil, errors.New("unknown error")
}
func main() {
var o map[string]interface{}
err := json.Unmarshal([]byte(`{
"foo": "bar",
"baz": [1, "haha", {
"lol": 3
}]
}`), &o)
if err != nil {
panic(err)
}
result, err := get(o, []string{"baz", "3", "lol"})
if err != nil {
panic(err)
}
fmt.Println(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment