在golang中解析深层嵌套的数组

huangapple go评论89阅读模式
英文:

Unmarshall deep nested array in golang

问题

我正在尝试迭代"List"中的"Inner"元素,但只能恢复最后一个"Inner - type",即"c1":

jsonData := []byte(`{
    "List": [{
        "Inner":{"type":"a1"},   
        "Inner":{"type":"b1"},
        "Inner":{"type":"c1"}
    }]
}`)

type Test struct {
    List []struct {
        Inner struct {
            Type string `json:"type"` 
        } `json:"Inner"`
    } `json:"List"`
}

var test Test
json.Unmarshal(jsonData, &test)

fmt.Println(test.List[0].Inner.Type)

那么,有没有办法打印出"List"中的所有元素呢?

英文:

I am trying to iterate over the "Inner" elements in "List", but only the last "Inner - type" is recovered, ie, "c1":

jsonData := []byte(`{
"List": [{
	"Inner":{"type":"a1"},   	
	"Inner":{"type":"b1"},
    "Inner":{"type":"c1"}
}]}`)

type Test struct {
  List []struct {
    Inner struct {
      Type string `json:"type"` 
    } `json:"Inner"`
  } `json:"List"`
}

var test Test
json.Unmarshal(jsonData, &test)

fmt.Println(test.List[0].Inner.Type)

So, Is there any way to print all elements in "List" ?

答案1

得分: 2

你可能需要为[]List对象中的对象选择一种类型,并使用自定义逻辑实现JSONUnmarshaller接口,以实现以下功能。

package main

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
)

type Inner struct {
	Type string `json:"type"`
}

type List []Inner

type Test struct {
	List []List `json:"List"`
}

func main() {
	jsonData := []byte(`{
"List": [{
    "Inner":{"type":"a1"},      
    "Inner":{"type":"b1"},
    "Inner":{"type":"c1"}
}]}`)

	var test Test
	err := json.Unmarshal(jsonData, &test)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, v := range test.List[0] {
		fmt.Println(v.Type)
	}
}

func (l *List) UnmarshalJSON(bytes []byte) error {
	out := make(List, 0)
	re := regexp.MustCompile(`"Inner":{.*}`)
	objects := re.FindAll(bytes, -1)
	for _, v := range objects {
		inner := Inner{}
		s := strings.TrimLeft(string(v), `"Inner":`)
		err := json.Unmarshal([]byte(s), &inner)
		if err != nil {
			return err
		}
		out = append(out, inner)
	}
	*l = out
	return nil
}

输出:

a1
b1
c1
英文:

you might need to decide on a type for the objects coming inside the []List object, and implement the JSONUnmarshaller interface with a custom logic as follows to achieve this.

package main

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
)

type Inner struct{
	Type string `json:"type"`
}

type List []Inner

type Test struct {
	List [] List `json:"List"`
}

func main() {
	jsonData := []byte(`{
"List": [{
    "Inner":{"type":"a1"},      
    "Inner":{"type":"b1"},
    "Inner":{"type":"c1"}
}]}`)

	var test Test
	err := json.Unmarshal(jsonData, &test)
	if err != nil{
		fmt.Println(err)
		return
	}

	for _,v := range test.List[0]{
		fmt.Println(v.Type)
	}
}

func (l *List) UnmarshalJSON(bytes []byte) error {
	out := make(List,0)
	re := regexp.MustCompile(`"Inner":{.*}`)
	objects := re.FindAll(bytes,-1)
	for _,v := range objects{
		inner := Inner{}
		s := strings.TrimLeft(string(v),`"Inner":`)
		err := json.Unmarshal([]byte(s),&inner)
		if err != nil{
			return err
		}
		out = append(out,inner)
	}
	*l = out
	return nil
}

output:

a1
b1
c1

答案2

得分: 1

在JSON中,同一个对象上不能有多个相同的键:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

console.log(JSON.parse(`{
    &quot;Inner&quot;:{&quot;type&quot;:&quot;a1&quot;},      
    &quot;Inner&quot;:{&quot;type&quot;:&quot;b1&quot;},
    &quot;Inner&quot;:{&quot;type&quot;:&quot;c1&quot;}
}`))

<!-- end snippet -->

所以,除非编写一个自定义的解析器,否则无法实现。

英文:

You can't have multiple identical keys on the same object in JSON:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

console.log(JSON.parse(`{
    &quot;Inner&quot;:{&quot;type&quot;:&quot;a1&quot;},      
    &quot;Inner&quot;:{&quot;type&quot;:&quot;b1&quot;},
    &quot;Inner&quot;:{&quot;type&quot;:&quot;c1&quot;}
}`))

<!-- end snippet -->

so without writing a custom unmarshaller, no.

huangapple
  • 本文由 发表于 2021年7月13日 08:47:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/68355244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定