英文:
golang: quickly access data of maps within maps
问题
{
"service": {
"auth": {
"token": {
"$t": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
英文:
So I've got the following bit of JSON and I want to pull out the "$t" value under "token". Continue for Go code...
{
"@encoding": "iso-8859-1",
"@version": "1.0",
"service": {
"auth": {
"expiresString": {
"$t": "2013-06-12T01:15:28Z"
},
"token": {
"$t": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"expires": {
"$t": "1370999728"
},
"key": {
"$t": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
I have the following snippet of Go code that unmarshals the json into an interface. Then I work my way down to the "$t" value of "token". This approach does work, but it's ugly.
My question: is there a faster way to access that value than by converting each map into an interface? I'm very new to Go and am not aware of many of the useful features of interfaces and maps.
var f interface{}
jerr := json.Unmarshal(body, &f)
m := f.(map[string]interface{})
ser := m["service"].(map[string]interface{})
a := ser["auth"].(map[string]interface{})
tok := a["token"].(map[string]interface{})
token := tok["$t"]
fmt.Fprintf(w, "Token: %v\n", token)
Thanks in advance!
答案1
得分: 12
如果这是你想要的唯一值,那么你可以使用一个匿名的struct
来定义数据的路径。
var m = new(struct{Service struct{Auth struct{Token map[string]string}}})
var err = json.Unmarshal([]byte(data), &m)
fmt.Println(m.Service.Auth.Token["$t"], err)
DEMO: http://play.golang.org/p/ZdKTzM5i57
如果不想使用map
作为最内层的数据,我们可以使用另一个struct
,但是我们需要提供一个字段标签来别名化名称。
var m = new(struct{Service struct{Auth struct{Token struct{T string `json:"$t"`}}}})
var err = json.Unmarshal([]byte(data), &m)
fmt.Println(m.Service.Auth.Token.T, err)
DEMO: http://play.golang.org/p/NQTpaUvanx
英文:
If that's the only value you want, then how about using an anonymous struct
that defines the path to your data.
var m = new(struct{Service struct{Auth struct{Token map[string]string}}})
var err = json.Unmarshal([]byte(data), &m)
fmt.Println(m.Service.Auth.Token["$t"], err)
DEMO: http://play.golang.org/p/ZdKTzM5i57
Instead of using a map
for the innermost data, we could use another struct, but we'd need to provide a field tag to alias the name.
var m = new(struct{Service struct{Auth struct{Token struct{T string `json:"$t"`}}}})
var err = json.Unmarshal([]byte(data), &m)
fmt.Println(m.Service.Auth.Token.T, err)
答案2
得分: 7
你可以使用我们的stew包中的objects.Map
,它为地图提供了点访问器:
objects.Map(data).Get("service.auth.token")
请参阅http://godoc.org/github.com/stretchr/stew/objects
英文:
OR you can use objects.Map
from our stew package, it gives you dot accessors for maps:
objects.Map(data).Get("service.auth.token")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论