英文:
How to get values from list nested within list in JSON
问题
我有一个类似于以下结构的JSON:
{
"persons":[
{
"name":"mark",
"surname":"zuckerberg",
"data":[
{
"userid":"09210",
"username":"mark290",
"registered_date":"10-01-2017"
},
{
"userid":"092240",
"username":"mark291",
"registered_date":"11-01-2017"
}
]
},
{
"name":"bill",
"surname":"clinton",
"data":[
{
"userid":"0442340",
"username":"billy",
"registered_date":"10-01-2000"
},
{
"userid":"89472894",
"username":"billary",
"registered_date":"11-01-2015"
}
]
}
]
}
我需要获取每个人的每个用户名。目前,在我完全不熟悉的Go语言中,我只能获取"data"中的单个JSON,使用以下代码片段:
j := []byte(data)
var f interface{}
err := json.Unmarshal(j, &f)
m := f.(map[string]interface{})
for _, item := range m["persons"].([]interface{}) {
fmt.Printf("%v", item.(map[string]interface{})["data"])
}
fmt.Println(err)
我很难理解如何深入"data"中的每个JSON结构,以获取每个键值对。
英文:
I have a JSON structure such as:
{
"persons":[
{
"name":"mark",
"surname":"zuckerberg",
"data":[
{
"userid":"09210",
"username":"mark290",
"registered_date":"10-01-2017"
},
{
"userid":"092240",
"username":"mark291",
"registered_date":"11-01-2017"
}
]
},
{
"name":"bill",
"surname":"clinton",
"data":[
{
"userid":"0442340",
"username":"billy",
"registered_date":"10-01-2000"
},
{
"userid":"89472894",
"username":"billary",
"registered_date":"11-01-2015"
}
]
}
]
}
I need to fetch each username for each person.
Currently, in Go, which I am a total newbie at, I can get only the single JSONS within "data", with this snippet:
j := []byte(data)
var f interface{}
err := json.Unmarshal(j, &f)
map := f.(map[string]interface{})
for _,item := range map["persons"].([]interface{}) {
fmt.Printf("%v", item.(map[string]interface{})["data"])
fmt.Println(err)
I struggle to understand how to dive within each JSON struct within data in order to get each key,value pair.
答案1
得分: 3
你可以定义与JSON
字节对应的准确嵌套结构,以进行Unmarshal
操作。
package main
import (
"encoding/json"
"fmt"
)
type Trunk struct {
Persons []Person `json:"persons"`
}
type Person struct {
Name string `json:"name"`
Surname string `json:"surname"`
Data []User `json:"data"`
}
type User struct {
Userid string `json:"userid"`
Username string `json:"username"`
Registered_date string `json:"registered_date"`
}
func main() {
rawstring := []byte(`
{
"persons":[
{
"name":"mark",
"surname":"zuckerberg",
"data":[
{
"userid":"09210",
"username":"mark290",
"registered_date":"10-01-2017"
},
{
"userid":"092240",
"username":"mark291",
"registered_date":"11-01-2017"
}
]
},
{
"name":"bill",
"surname":"clinton",
"data":[
{
"userid":"0442340",
"username":"billy",
"registered_date":"10-01-2000"
},
{
"userid":"89472894",
"username":"billary",
"registered_date":"11-01-2015"
}
]
}
]
}
`)
jsondata := Trunk{}
if err := json.Unmarshal(rawstring, &jsondata); err == nil {
fmt.Println(jsondata)
// print first username of first person
// fmt.Println(jsondata.Persons[0].Data[0].Username)
// print each username of each person
for _, person := range jsondata.Persons {
for _, d := range person.Data {
fmt.Println(d.Username)
}
}
} else {
fmt.Println("Unmarshal failed!")
}
}
或者使用更紧凑的结构定义:
type Trunk struct {
Persons []struct {
Name string `json:"name"`
Surname string `json:"surname"`
Data []struct {
Userid string `json:"userid"`
Username string `json:"username"`
Registered_date string `json:"registered_date"`
} `json:"data"`
} `json:"persons"`
}
英文:
You can define the accurate nested structure corresponding to the JSON
bytes, to Unmarshal
.
package main
import (
"encoding/json"
"fmt"
)
type Trunk struct {
Persons []Person `json:"persons"`
}
type Person struct {
Name string `json:"name"`
Surname string `json:"surname"`
Data []User `json:"data"`
}
type User struct {
Userid string `json:"userid"`
Username string `json:"username"`
Registered_date string `json:"registered_date"`
}
func main() {
rawstring := []byte(`
{
"persons":[
{
"name":"mark",
"surname":"zuckerberg",
"data":[
{
"userid":"09210",
"username":"mark290",
"registered_date":"10-01-2017"
},
{
"userid":"092240",
"username":"mark291",
"registered_date":"11-01-2017"
}
]
},
{
"name":"bill",
"surname":"clinton",
"data":[
{
"userid":"0442340",
"username":"billy",
"registered_date":"10-01-2000"
},
{
"userid":"89472894",
"username":"billary",
"registered_date":"11-01-2015"
}
]
}
]
}
`)
jsondata := Trunk{}
if err := json.Unmarshal(rawstring, &jsondata); err == nil {
fmt.Println(jsondata)
// print first username of first person
// fmt.Println(jsondata.Persons[0].Data[0].Username)
// print each username of each person
for _, person := range jsondata.Persons {
for _, d := range person.Data {
fmt.Println(d.Username)
}
}
} else {
fmt.Println("Unmarshal failed!")
}
}
Or use a more compact structure defination:
type Trunk struct {
Persons []struct {
Name string `json:"name"`
Surname string `json:"surname"`
Data []struct {
Userid string `json:"userid"`
Username string `json:"username"`
Registered_date string `json:"registered_date"`
} `json:"data"`
} `json:"persons"`
}
答案2
得分: 1
如果你想使用流式处理方法,你可以尝试使用Decoder来查找"username" Token,并通过"value"获取下一个Token。
dec := json.NewDecoder(strings.NewReader(rawstring))
for {
t, err := dec.Token()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
if val, ok := t.(string); ok && val == "username" {
t, err := dec.Token()
if err == io.EOF {
break
}
fmt.Println(t)
}
}
英文:
If you want to use streaming approach you can try to Decoder to find "username" Token and get next Token with "value".
dec := json.NewDecoder(strings.NewReader(rawstring))
for {
t, err := dec.Token()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
if val, ok := t.(string); ok && val == "username" {
t, err := dec.Token()
if err == io.EOF {
break
}
fmt.Println(t)
}
}
<kbd>PLAYGROUND</kbd>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论