【问题标题】:Get Array of Nested JSON Struct in GO在 GO 中获取嵌套的 JSON 结构数组
【发布时间】:2021-08-21 22:09:46
【问题描述】:

我是 GoLang 的新手,有一个关于从嵌套 JSON 数据填充数组的问题。我昨天查看了堆栈溢出,找不到这个确切的主题,只有相似的线程,但不提供直接的解决方案。

假设我有一些嵌套的 JSON 数据,如下所示:

如何创建嵌套结构来填充收盘价数组。我的代码如下。 我的目标是有一个数组,其中 arr = {157.92, 142.19, 148.26}

提前致谢!我非常感谢任何帮助!

{
  "history": {
    "day": [
      {
        "date": "2019-01-02",
        "open": 154.89,
        "high": 158.85,
        "low": 154.23,
        "close": 157.92,
        "volume": 37039737
      },
      {
        "date": "2019-01-03",
        "open": 143.98,
        "high": 145.72,
        "low": 142.0,
        "close": 142.19,
        "volume": 91312195
      },
      {
        "date": "2019-01-04",
        "open": 144.53,
        "high": 148.5499,
        "low": 143.8,
        "close": 148.26,
        "volume": 58607070
      }
      ...
    ]
  }
}
// DATA STRUCTURE
type Hist struct {
    History string `json:"history"`
}

type Date struct {
    Day string `json:"day"`
}

type Price struct {
    Close []string `json:"close"`
}

// HISTORICAL QUOTES
func get_quotes(arg1 string, arg2 string, arg3 string, arg4 string) []string {

    // arg1 = ticker symbol, arg2 = start, arg3 = end, arg4 = access token

    // TRADIER API
    apiUrl := "https://sandbox.tradier.com/v1/markets/history?symbol=" + arg1 + "&interval=daily&start=" + arg2 + "&end=" + arg3

    u, _ := url.ParseRequestURI(apiUrl)
    urlStr := u.String()

    client := &http.Client{}
    r, _ := http.NewRequest("GET", urlStr, nil)
    r.Header.Add("Authorization", "Bearer "+arg4)
    r.Header.Add("Accept", "application/json")

    resp, _ := client.Do(r)
    responseData, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(resp.Status)
    fmt.Println(string(responseData))

    var response Price
    json.NewDecoder(resp.Body).Decode(&response)

    fmt.Println(response.Close)

    return response.Close

}

【问题讨论】:

  • “我昨天查看了堆栈溢出,找不到这个确切的主题,只有类似的线程,但不提供直接解决方案。”您是否尝试过实施自己的解决方案?你能显示那个代码吗? SO 不是代码编写服务。
  • JSON 的“day”字段不包含 JSON 对象(其中解码可以匹配键“close”);相反,它包含一个列表。您在这里基本上有两个选择:1)将“day”的值解组为struct类型的切片,每个类型包含string类型的单个字段标记json:"close",然后对结果进行后处理:遍历结果切片并从切片的元素中提取值; 2) 使用 JSON 解码器的“流”工具来遍历列表值并在旅途中生成结果切片。我强烈建议现在坚持第一种方法。
  • The language is called Go——与你不说 PytongLang、JavaScriptLang 等的原因基本相同
  • @Adrian 是的,我已经尝试实施自己的解决方案,附在上面。
  • @kostix 你能举个例子吗,我不太确定我理解了

标签: arrays json go struct


【解决方案1】:

这样的东西应该可以满足您的需求。您的数据结构未正确反映 API 的响应。我使用this tool 快速将 JSON 值转换为 Go 结构类型。正确解码响应后,只需遍历每个 Day 结构并将 close 值附加到输出数组即可。

我添加了用于解码和映射值的核心内容。您可以通过组合已有的内容来自定义客户端、请求和标头。

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Response struct {
    History History `json:"history"`
}
type Day struct {
    Date   string  `json:"date"`
    Open   float64 `json:"open"`
    High   float64 `json:"high"`
    Low    float64 `json:"low"`
    Close  float64 `json:"close"`
    Volume int     `json:"volume"`
}
type History struct {
    Day []Day `json:"day"`
}

func main() {
    prices, err := closePrices()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(prices)
}

func closePrices() (out []float64, err error) {
    resp, err := http.Get("...")
    if err != nil {
        return
    }
    r := Response{}
    err = json.NewDecoder(resp.Body).Decode(&r)
    if err != nil {
        return
    }
    for _, d := range r.History.Day {
        out = append(out, d.Close)
    }
    return
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 2016-06-15
    相关资源
    最近更新 更多