英文:
Golang unmarshal array without key/value to stuct
问题
我正在尝试将来自Google Analytics API的JSON数组放入一个结构体中。
例如:
"rows": [
[
"female",
"18-24",
"1308"
],
[
"female",
"25-34",
"741"
]
]
通常情况下,我会有键/值对,这样我就可以使用json:"gender"
来放置。但是这里没有与之关联的键,所以它要搜索的值会发生变化。
结构体应该是:
type Row struct {
Gender string json:"gender"
AgeRange string json:"blah"
Count string json:"blah"
}
如果我执行len(jResp.Rows),我可以看到它获取了所有12行/数组,但字段是空的。
英文:
I'm trying to place a json array into a struct from Google Analytics API.
EG:
"rows": [
[
"female",
"18-24",
"1308"
],
[
"female",
"25-34",
"741"
]
]
Typically I'd have key/value so I can put json:"gender"
but there are no keys to associate with, so the values that it would search for change.
The struct would be:
type Row struct {
Gender string `json:"gender"`
AgeRange string `json:"blah"`
Count string `json:"blah"`
}
If I do len(jResp.Rows) I can see that it's grabbing all twelve rows/arrays but the fields are empty.
答案1
得分: 1
我不认为使用encoding/json
直接将该JSON解码为一个结构体切片是可能的,而不需要在你的Row
类型上首先实现一个UnmarshalJSON
方法。
func (r *Row) UnmarshalJSON(data []byte) error {
var s []string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
if len(s) >= 3 {
r.Gender = s[0]
r.AgeRange = s[1]
r.Count = s[2]
}
return nil
}
// 确保它是一个指向Row的切片
type Resp struct {
Rows []*Row `json:"rows"`
}
编辑:稍微修正了一下代码,使其能够编译。这里有一个可工作的示例:https://play.golang.org/p/eqVQj65xJv。
你也可以先将数据解码为一个字符串切片,然后循环遍历结果来构建你的结构体值。
type Resp struct {
Rows [][]string `json:"rows"`
}
type Row struct {
Gender string `json:"gender"`
AgeRange string `json:"blah"`
Count string `json:"blah"`
}
var resp Resp
if err := json.Unmarshal(data, &resp); err != nil {
panic(err)
}
var rows = make([]Row, len(resp.Rows))
for i, r := range resp.Rows {
rows[i] = Row{
Gender: r[0],
AgeRange: r[1],
Count: r[2],
}
}
编辑:也修正了这个。https://play.golang.org/p/Otb7iULSh3
英文:
I don't think it's possible, with encoding/json
to directly decode that json into a slice of structs without first implementing a UnmarshalJSON
method on your Row
type.
func (r *Row) UnmarshalJSON(data []byte) error {
var s []string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
if len(s) >= 3 {
r.Gender = s[0]
r.AgeRange = s[1]
r.Count = s[2]
}
return nil
}
// make sure it's a slice of pointers to Row
type Resp struct {
Rows []*Row `json:"rows"`
}
Edit: fixed the code a little to make it actually compile. Heres a working example https://play.golang.org/p/eqVQj65xJv.
You could also just decode the data first into a slice of strings and then loop over the result to build you struct values.
type Resp struct {
Rows [][]string `json:"rows"`
}
type Row struct {
Gender string `json:"gender"`
AgeRange string `json:"blah"`
Count string `json:"blah"`
}
var resp jResp
if err := json.Unmarshal(data, &resp); err != nil {
panic(err)
}
var rows = make([]Row, len(resp.Rows))
for i, r := range resp.Rows {
rows[i] = Row{
Gender: r[0],
AgeRange: r[1],
Count: r[2],
}
}
Edit: fixed this one as well. https://play.golang.org/p/Otb7iULSh3
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论