The issue I had is that sometimes I will need to get at a value that is deeply
nested. Normally you would need to do a type assertion at each level, so I went
ahead and just made a method that takes a map[string]interface{}
and a
string
key, and returns the resulting map[string]interface{}
.
The issue that cropped up for me was that at some depths you will encounter a Slice instead of Map. So I also added methods to return a Slice from Map, and Map from Slice. I didnt do one for Slice to Slice, but you could easily add that if needed. Here are the methods:
package main
type Slice []interface{}
type Map map[string]interface{}
func (m Map) M(s string) Map {
return m[s].(map[string]interface{})
}
func (m Map) A(s string) Slice {
return m[s].([]interface{})
}
func (a Slice) M(n int) Map {
return a[n].(map[string]interface{})
}
and example code:
package main
import (
"encoding/json"
"fmt"
"log"
"os"
)
func main() {
o, e := os.Open("a.json")
if e != nil {
log.Fatal(e)
}
in_m := Map{}
json.NewDecoder(o).Decode(&in_m)
out_m := in_m.
M("contents").
M("sectionListRenderer").
A("contents").
M(0).
M("musicShelfRenderer").
A("contents").
M(0).
M("musicResponsiveListItemRenderer").
M("navigationEndpoint").
M("browseEndpoint")
fmt.Println(out_m)
}