在 GO 中获取嵌套的 JSON 结构数组

Posted

技术标签:

【中文标题】在 GO 中获取嵌套的 JSON 结构数组【英文标题】:Get Array of Nested JSON Struct in GO 【发布时间】: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 你能举个例子吗,我不太确定我理解了 【参考方案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

【讨论】:

以上是关于在 GO 中获取嵌套的 JSON 结构数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上通过 GSON 从嵌套 JSON 数组中获取价值? [复制]

从没有名称Android的嵌套数组JSON获取数据

无法从 json-server 获取嵌套的对象数组

从flutter中的多个嵌套json数组中获取值

无法从python中的json数组获取嵌套对象

在java Android中获取JSON嵌套对象的特定索引