从Json中提取数组中的值

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

Extract value from an array in a Json

问题

我正在尝试获取"boots"的值

我的主要函数

var json := `{
  "identifier": "1",
  "name": "dumbname",
  "person": {
    "items": null,
    "inventory": [
      {
        "T-shirt": "black",
        "Backpack": {
          "BigPocket": {
            "spell": "healing",
            "boots": "speed",
            "shampoo": "Head & Shoulders"
          }
        }
      }
    ],
    "Pockets": null
  }
}`

var res map[string]interface{}

json.Unmarshal([]byte(json), &res)

test(res) 

测试函数

    func test(t interface{}) {
	  switch reflect.TypeOf(t).Kind() {
	   case reflect.Slice:
		s := reflect.ValueOf(t)
	for i := 0; i < s.Len(); i++ {
		fmt.Println(s.Index(i))
	    }
	  }
    }

但是当我编译时什么都没有得到
如果有其他方法可以获取Json中的"boot"值吗?

英文:

I'm trying to get "boots" value

My func main

varjson:=`{
  &quot;identifier&quot;: &quot;1&quot;,
  &quot;name&quot;: &quot;dumbname&quot;,
  &quot;person&quot;: {
    &quot;items&quot;: null,
    &quot;inventory&quot;: [
      {
        &quot;T-shirt&quot;: &quot;black&quot;,
        &quot;Backpack&quot;: {
          &quot;BigPocket&quot;: {
            &quot;spell&quot;: &quot;healing&quot;,
            &quot;boots&quot;: &quot;speed&quot;,
            &quot;shampoo&quot;: &quot;Head &amp; Shoulders&quot;
          }
        }
      }
    ],
    &quot;Pockets&quot;: null
  }
}`

var res map[string]interface{}

json.Unmarshal([]byte(varjson), &amp;res)

test(res) 

test function

    func test(t interface{}) {
	  switch reflect.TypeOf(t).Kind() {
	   case reflect.Slice:
		s := reflect.ValueOf(t)
	for i := 0; i &lt; s.Len(); i++ {
		fmt.Println(s.Index(i))
	    }
	  }
    }

But when I compile I get nothing
If is there another way to get the "boot" value in the Json?

答案1

得分: 1

假设你可以使用类型,根据你的评论(幸运的是,我完全同意colm的观点,尝试反映结构是困难的)。

一旦你有了一个类型,导航就非常容易。

具体来说,fmt.Println(res.Person.Inventory[0].Backpack.BigPocket.Boots) 将返回 boots 的值。需要注意的是,Inventory 是一个切片,所以你可能需要遍历它,而我在这里直接访问了它,如果 Inventory 是空的或者有其他元素,这样做是不好的。

package main

import (
	"encoding/json"
	"fmt"
)

type AutoGenerated struct {
	Identifier string `json:"identifier"`
	Name       string `json:"name"`
	Person     struct {
		Items     interface{} `json:"items"`
		Inventory []struct {
			TShirt   string `json:"T-shirt"`
			Backpack struct {
				BigPocket struct {
					Spell   string `json:"spell"`
					Boots   string `json:"boots"`
					Shampoo string `json:"shampoo"`
				} `json:"BigPocket"`
			} `json:"Backpack"`
		} `json:"inventory"`
		Pockets interface{} `json:"Pockets"`
	} `json:"person"`
}

func main() {
	var varjson = `{
		"identifier": "1",
		"name": "dumbname",
		"person": {
			"items": null,
			"inventory": [
				{
					"T-shirt": "black",
					"Backpack": {
						"BigPocket": {
							"spell": "healing",
							"boots": "speed",
							"shampoo": "Head & Shoulders"
						}
					}
				}
			],
			"Pockets": null
		}
	}`

	var res AutoGenerated
	json.Unmarshal([]byte(varjson), &res)

	fmt.Println(res.Person.Inventory[0].Backpack.BigPocket.Boots)
}

在你的原始代码中,问题在于你的 switch 语句只覆盖了一个切片,但初始对象是一个映射。所以你的 switch 最初找不到匹配项。

英文:

Assuming you can use types, based on your comment (thankfully cause totally agree with colm, trying to reflect the structure is rough.

Once you have a type its super easy to navigate.

specifically fmt.Println(res.Person.Inventory[0].Backpack.BigPocket.Boots)
would net you the boots value. Bearing in mind that Inventory is a slice so you probably need to iterate over that, whereas here I have directly accessed it, which will be bad if Inventory is empty or there are other elements.

package main

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
)

type AutoGenerated struct {
	Identifier string `json:&quot;identifier&quot;`
	Name       string `json:&quot;name&quot;`
	Person     struct {
		Items     interface{} `json:&quot;items&quot;`
		Inventory []struct {
			TShirt   string `json:&quot;T-shirt&quot;`
			Backpack struct {
				BigPocket struct {
					Spell   string `json:&quot;spell&quot;`
					Boots   string `json:&quot;boots&quot;`
					Shampoo string `json:&quot;shampoo&quot;`
				} `json:&quot;BigPocket&quot;`
			} `json:&quot;Backpack&quot;`
		} `json:&quot;inventory&quot;`
		Pockets interface{} `json:&quot;Pockets&quot;`
	} `json:&quot;person&quot;`
}

func main() {
	varjson := `{
  &quot;identifier&quot;: &quot;1&quot;,
  &quot;name&quot;: &quot;dumbname&quot;,
  &quot;person&quot;: {
    &quot;items&quot;: null,
    &quot;inventory&quot;: [
      {
        &quot;T-shirt&quot;: &quot;black&quot;,
        &quot;Backpack&quot;: {
          &quot;BigPocket&quot;: {
            &quot;spell&quot;: &quot;healing&quot;,
            &quot;boots&quot;: &quot;speed&quot;,
            &quot;shampoo&quot;: &quot;Head &amp; Shoulders&quot;
          }
        }
      }
    ],
    &quot;Pockets&quot;: null
  }
}`

	var res AutoGenerated
	json.Unmarshal([]byte(varjson), &amp;res)
	
	fmt.Println(res.Person.Inventory[0].Backpack.BigPocket.Boots)
}

In your original, whats wrong is your switch statement only covers a slice, but the initial object is a map. So your switch is not finding a match initially

huangapple
  • 本文由 发表于 2021年9月17日 06:18:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/69215789.html
匿名

发表评论

匿名网友

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

确定