How do I parse JSON in Go where array elements have more than one type?

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

How do I parse JSON in Go where array elements have more than one type?

问题

如何将来自https://api.twitchinsights.net/v1/bots/online的JSON响应解析为Go中的数组,并遍历每个条目?

我不理解结构,因为只有值没有键...

有人可以帮忙解释一下这是如何工作的吗?

我已经将其映射,但是我得到了像这样的东西

map[_total:216 bots:[[anotherttvviewer 67063 1.632071051e+09] [defb 26097 1.632071051e+09] [commanderroot 17531 1.632071048e+09] [apparentlyher 16774 1.63207105e+09]... 

但是我无法遍历这个映射。

英文:

How can I parse a JSON response from https://api.twitchinsights.net/v1/bots/online to an array in Go and iterate over every entry?

I dont understand the struct because there are no keys only values...

Can anyone please help and explain how this works?

I've mapped it but then I get something like

map[_total:216 bots:[[anotherttvviewer 67063 1.632071051e+09] [defb 26097 1.632071051e+09] [commanderroot 17531 1.632071048e+09] [apparentlyher 16774 1.63207105e+09]... 

But I cant iterate over the map.

答案1

得分: 3

因为你正在使用的 API 返回的数据可能是字符串或数字(在数组的数组属性 bots 中),所以你需要将每个数组元素的类型设置为 []interface{},因为空接口(https://tour.golang.org/methods/14)可以在运行时适用于任何类型。

type response struct {
	Bots  [][]interface{} `json:"bots"`
	Total int             `json:"_total"`
}

然后,在遍历切片中的每个项时,你可以使用反射来检查其类型。

理想情况下,API 应该以一种模式返回数据,其中每个 JSON 数组元素与其数组中的其他元素具有相同的 JSON 类型。这将更容易解析,特别是在使用静态类型语言如 Go 时。

例如,API 可以返回如下数据:

{
  "bots": [
    {
      "stringProp": "value1",
      "numberProps": [
        1,
        2
      ]
    }
  ],
  "_total": 1
}

然后,你可以编写一个表示 API 响应的结构体,而无需使用空接口:

type bot struct {
    StringProp  string    `json:"stringProp"`
	NumberProps []float64 `json:"numberProps"`
}

type response struct {
	Bots  []bot `json:"bots"`
	Total int   `json:"_total"`
}

但有时你无法控制你正在使用的 API,因此你需要以更动态的方式解析响应中的数据。如果你可以控制 API,你应该考虑以这种方式返回数据。

英文:

Because the API you're working with returns data where it could be a string or a number (in the array of arrays property bots), you'll need to use []interface{} as the type for each element of that array because the empty interface (https://tour.golang.org/methods/14) works for any type at run time.

type response struct {
	Bots  [][]interface{} `json:"bots"`
	Total int             `json:"_total"`
}

Then, as you iterate through each item in the slice, you can check its type using reflection.

It would be ideal for the API to return data in a schema where every JSON array element has the same JSON type as every other element in its array. This will be easier to parse, especially using statically typed languages like Go.

For example, the API could return data like:

{
  "bots": [
    {
      "stringProp": "value1",
      "numberProps": [
        1,
        2
      ]
    }
  ],
  "_total": 1
}

Then, you could write a struct representing the API response without using the empty interface:

type bot struct {
    StringProp  string    `json:"stringProp"`
	NumberProps []float64 `json:"numberProps"`
}

type response struct {
	Bots  []bot `json:"bots"`
	Total int   `json:"_total"`
}

But sometimes you're not in control of the API you're working with, so you need to be willing to parse the data from the response in a more dynamic way. If you do have control of the API, you should consider returning the data this way instead.

huangapple
  • 本文由 发表于 2021年9月20日 01:26:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/69245554.html
匿名

发表评论

匿名网友

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

确定