从Json中提取数组中的值

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

Extract value from an array in a Json

问题

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

我的主要函数

  1. var json := `{
  2. "identifier": "1",
  3. "name": "dumbname",
  4. "person": {
  5. "items": null,
  6. "inventory": [
  7. {
  8. "T-shirt": "black",
  9. "Backpack": {
  10. "BigPocket": {
  11. "spell": "healing",
  12. "boots": "speed",
  13. "shampoo": "Head & Shoulders"
  14. }
  15. }
  16. }
  17. ],
  18. "Pockets": null
  19. }
  20. }`
  21. var res map[string]interface{}
  22. json.Unmarshal([]byte(json), &res)
  23. test(res)

测试函数

  1. func test(t interface{}) {
  2. switch reflect.TypeOf(t).Kind() {
  3. case reflect.Slice:
  4. s := reflect.ValueOf(t)
  5. for i := 0; i < s.Len(); i++ {
  6. fmt.Println(s.Index(i))
  7. }
  8. }
  9. }

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

英文:

I'm trying to get "boots" value

My func main

  1. varjson:=`{
  2. &quot;identifier&quot;: &quot;1&quot;,
  3. &quot;name&quot;: &quot;dumbname&quot;,
  4. &quot;person&quot;: {
  5. &quot;items&quot;: null,
  6. &quot;inventory&quot;: [
  7. {
  8. &quot;T-shirt&quot;: &quot;black&quot;,
  9. &quot;Backpack&quot;: {
  10. &quot;BigPocket&quot;: {
  11. &quot;spell&quot;: &quot;healing&quot;,
  12. &quot;boots&quot;: &quot;speed&quot;,
  13. &quot;shampoo&quot;: &quot;Head &amp; Shoulders&quot;
  14. }
  15. }
  16. }
  17. ],
  18. &quot;Pockets&quot;: null
  19. }
  20. }`
  21. var res map[string]interface{}
  22. json.Unmarshal([]byte(varjson), &amp;res)
  23. test(res)

test function

  1. func test(t interface{}) {
  2. switch reflect.TypeOf(t).Kind() {
  3. case reflect.Slice:
  4. s := reflect.ValueOf(t)
  5. for i := 0; i &lt; s.Len(); i++ {
  6. fmt.Println(s.Index(i))
  7. }
  8. }
  9. }

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 是空的或者有其他元素,这样做是不好的。

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type AutoGenerated struct {
  7. Identifier string `json:"identifier"`
  8. Name string `json:"name"`
  9. Person struct {
  10. Items interface{} `json:"items"`
  11. Inventory []struct {
  12. TShirt string `json:"T-shirt"`
  13. Backpack struct {
  14. BigPocket struct {
  15. Spell string `json:"spell"`
  16. Boots string `json:"boots"`
  17. Shampoo string `json:"shampoo"`
  18. } `json:"BigPocket"`
  19. } `json:"Backpack"`
  20. } `json:"inventory"`
  21. Pockets interface{} `json:"Pockets"`
  22. } `json:"person"`
  23. }
  24. func main() {
  25. var varjson = `{
  26. "identifier": "1",
  27. "name": "dumbname",
  28. "person": {
  29. "items": null,
  30. "inventory": [
  31. {
  32. "T-shirt": "black",
  33. "Backpack": {
  34. "BigPocket": {
  35. "spell": "healing",
  36. "boots": "speed",
  37. "shampoo": "Head & Shoulders"
  38. }
  39. }
  40. }
  41. ],
  42. "Pockets": null
  43. }
  44. }`
  45. var res AutoGenerated
  46. json.Unmarshal([]byte(varjson), &res)
  47. fmt.Println(res.Person.Inventory[0].Backpack.BigPocket.Boots)
  48. }

在你的原始代码中,问题在于你的 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.

  1. package main
  2. import (
  3. &quot;encoding/json&quot;
  4. &quot;fmt&quot;
  5. )
  6. type AutoGenerated struct {
  7. Identifier string `json:&quot;identifier&quot;`
  8. Name string `json:&quot;name&quot;`
  9. Person struct {
  10. Items interface{} `json:&quot;items&quot;`
  11. Inventory []struct {
  12. TShirt string `json:&quot;T-shirt&quot;`
  13. Backpack struct {
  14. BigPocket struct {
  15. Spell string `json:&quot;spell&quot;`
  16. Boots string `json:&quot;boots&quot;`
  17. Shampoo string `json:&quot;shampoo&quot;`
  18. } `json:&quot;BigPocket&quot;`
  19. } `json:&quot;Backpack&quot;`
  20. } `json:&quot;inventory&quot;`
  21. Pockets interface{} `json:&quot;Pockets&quot;`
  22. } `json:&quot;person&quot;`
  23. }
  24. func main() {
  25. varjson := `{
  26. &quot;identifier&quot;: &quot;1&quot;,
  27. &quot;name&quot;: &quot;dumbname&quot;,
  28. &quot;person&quot;: {
  29. &quot;items&quot;: null,
  30. &quot;inventory&quot;: [
  31. {
  32. &quot;T-shirt&quot;: &quot;black&quot;,
  33. &quot;Backpack&quot;: {
  34. &quot;BigPocket&quot;: {
  35. &quot;spell&quot;: &quot;healing&quot;,
  36. &quot;boots&quot;: &quot;speed&quot;,
  37. &quot;shampoo&quot;: &quot;Head &amp; Shoulders&quot;
  38. }
  39. }
  40. }
  41. ],
  42. &quot;Pockets&quot;: null
  43. }
  44. }`
  45. var res AutoGenerated
  46. json.Unmarshal([]byte(varjson), &amp;res)
  47. fmt.Println(res.Person.Inventory[0].Backpack.BigPocket.Boots)
  48. }

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:

确定