英文:
Get Array of Nested JSON Struct in GO
问题
我是新手GoLang,对于从嵌套的JSON数据中填充数组有一个问题。我昨天在Stack Overflow上查找了一下,但没有找到确切的主题,只有一些类似的帖子,但没有提供直接的解决方案。
假设我有一些嵌套的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
}
...
]
}
}
// 数据结构
type Hist struct {
History string `json:"history"`
}
type Date struct {
Day string `json:"day"`
}
type Price struct {
Close []string `json:"close"`
}
// 历史报价
func get_quotes(arg1 string, arg2 string, arg3 string, arg4 string) []string {
// arg1 = 股票代码, arg2 = 开始日期, arg3 = 结束日期, arg4 = 访问令牌
// 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
}
英文:
I am new to GoLang, and have a question about filling an array from nested JSON data. I have looked through Stack overflow yesterday and cannot find this exact topic, only threads that are similar, but do not provide a direct solution.
Lets say I have some nested JSON data like what is given below:
How can I create a nested struct to fill an array of the close prices. My code is given below.
My goal is to have an array where, arr = {157.92, 142.19, 148.26}
Thanks in advance! I greatly appreciate any help!
{
"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
}
答案1
得分: 4
以下是翻译好的内容:
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
}
这段代码应该能满足你的需求。你的数据结构没有正确地反映API的响应。我使用了这个工具来快速将JSON值转换为Go结构体类型。一旦你正确解码了响应,只需要遍历每个Day
结构并将close
值追加到输出数组中。
我添加了解码和映射值的核心部分。你可以通过组合你已经拥有的内容来自定义客户端、请求和标头。
请注意,代码中的http.Get("...")
需要替换为你实际的API请求地址。
英文:
Something like this should give you what you need. Your data structure does not correctly reflect the response from the API. I used this tool to quickly convert the JSON value into a Go struct type. Once you're decoding the response correctly, then it's just a matter of iterating over each Day
struct and appending the close
value to an output array.
I added the core stuff for decoding and mapping the values. You can handle customizing the client, request, and headers however you'd like by combining what you've already got.
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论