英文:
Golang consume json with dynamic relevant keys
问题
我是GO的新手,我正在尝试使用GO从各种API中获取JSON数据,并将它们放入结构体中。其中一个结构体的数据格式如下:
{"MS": {
"last":"25",
"highestBid":"20"},
"GE": {
"last": "24",
"highestBid": "22"}
}
虽然我可以找到关于使用动态键进行消费的信息,但我找到的所有示例都将最外层的键视为任意和无关紧要的。我需要将其作为键值对使用,如下所示:
{"MarketName": "GE", "last":"24","highestBid":"22"}
我了解使用接口映射,但我无法弄清楚如何将动态键映射到结构体中的键值对。我在playground上找到了一个示例代码,其中省略了需要的键。代码如下:
package main
import (
"encoding/json"
"fmt"
)
var jsonBytes = []byte(`
{"MS": {
"last":"25",
"highestBid":"20"},
"GE": {
"last": "24",
"highestBid": "22"}
}`)
type Market struct {
Last string
HighestBid string
}
func main() {
// Unmarshal using a generic interface
var f interface{}
err := json.Unmarshal(jsonBytes, &f)
if err != nil {
fmt.Println("Error parsing JSON: ", err)
}
fmt.Println(f)
}
目前它的输出是:
map[MS:map[last:25 highestBid:20] GE:map[highestBid:22 last:24]]
正如我所说,我是GO的新手,我非常感谢任何帮助和解释。
英文:
I am new to GO and I am trying to consume json data from a variety of API's using GO and place them in struct's one of them Formats the data like so
{"MS": {
"last":"25",
"highestBid":"20"},
"GE": {
"last": "24",
"highestBid": "22"}
}
While I can find information on Consuming with dynamic keys, all the examples I found throw away the Outer most key as arbitrary and irrelevant. I need to use it as a key value pair like bellow:
{"MarketName": "GE", "last":"24","higestBid":"22"}
I understand Using Interface map but I cant figure out how to map the dynamic key to the struct as a key : value pair like above. My Code example to map leaving out the need key can be found at play ground Relevant Code
package main
import (
"encoding/json"
"fmt"
)
var jsonBytes = []byte(`
{"MS": {
"last":"25",
"highestBid":"20"},
"GE": {
"last": "24",
"highestBid": "22"}
}`)
type Market struct {
Last string
HighestBid string
}
func main() {
// Unmarshal using a generic interface
var f interface{}
err := json.Unmarshal(jsonBytes, &f)
if err != nil {
fmt.Println("Error parsing JSON: ", err)
}
fmt.Println(f)
}
as it stands it outputs
map[MS:map[last:25 highestBid:20] GE:map[highestBid:22 last:24]]
As I stated I am new to GO and as much help and explanation that i can get would be very appreciated
答案1
得分: 0
你已经完成了一半的工作,只需要将数据解组到你的结构体中,然后稍微处理一下数据:
type Market struct {
Name string
Last string
HighestBid string
}
func main() {
// 使用通用接口进行解组
var f map[string]Market
err := json.Unmarshal(jsonBytes, &f)
if err != nil {
fmt.Println("解析JSON时出错:", err)
return
}
markets := make([]Market, 0, len(f))
for k, v := range f {
v.Name = k
markets = append(markets, v)
}
fmt.Println(markets)
}
这里有一个可工作的示例:https://play.golang.org/p/iagx8RWFfx_k
英文:
You're halfway there already, you just need to unmarshal into your struct and then massage the data a little:
type Market struct {
Name string
Last string
HighestBid string
}
func main() {
// Unmarshal using a generic interface
var f map[string]Market
err := json.Unmarshal(jsonBytes, &f)
if err != nil {
fmt.Println("Error parsing JSON: ", err)
return
}
markets := make([]Market, 0, len(f))
for k,v := range f {
v.Name = k
markets = append(markets,v)
}
fmt.Println(markets)
}
Working example here: https://play.golang.org/p/iagx8RWFfx_k
答案2
得分: 0
如果Markets
的一个切片是对你有用的数据结构,你可能希望给它取一个别名,并实现MarketList.UnmarshalJSON([]byte)
方法,代码如下:
type Market struct {
MarketName string
Last string
HighestBid string
}
type MarketList []Market
func (ml *MarketList) UnmarshalJSON(b []byte) error {
tmp := map[string]Market{}
err := json.Unmarshal(b, &tmp)
if err != nil {
return err
}
var l MarketList
for k, v := range tmp {
v.MarketName = k
l = append(l, v)
}
*ml = l
return nil
}
func main() {
ml := MarketList{}
// 直接解组为 []Market 别名
_ = json.Unmarshal(jsonBytes, &ml)
fmt.Printf("%+v\n", ml)
}
英文:
If a slice of Markets is a data structure that's going to be useful to you, you might wish to alias it and implement MarketList.UnmarshalJSON([]byte)
, like so:
type Market struct {
MarketName string
Last string
HighestBid string
}
type MarketList []Market
func (ml *MarketList) UnmarshalJSON(b []byte) error {
tmp := map[string]Market{}
err := json.Unmarshal(b, &tmp)
if err != nil {
return err
}
var l MarketList
for k, v := range tmp {
v.MarketName = k
l = append(l, v)
}
*ml = l
return nil
}
func main() {
ml := MarketList{}
// Unmarshal directly into a []Market alias
_ = json.Unmarshal(jsonBytes, &ml)
fmt.Printf("%+v\n", ml)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论