Golang使用动态相关键消耗json

时间:2018-01-23 22:10:37

标签: json go dynamic unmarshalling

我是GO的新手,我正在尝试使用GO从各种API中使用json数据并将它们放在struct的其中一个中格式化数据如此

{"MS": {
   "last":"25",
"highestBid":"20"},
"GE": {        
    "last": "24",        
    "highestBid": "22"}
}

虽然我可以找到有关使用动态密钥进行消费的信息,但我发现的所有示例都将外部最常用密钥丢弃为任意且无关紧要。我需要将它用作关键值对,如下:

{"MarketName": "GE", "last":"24","higestBid":"22"}

我理解使用接口映射,但我无法弄清楚如何将动态键映射到结构作为键:值对,如上所述。可以在游戏场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)



}

因为它代表输出

map[MS:map[last:25 highestBid:20] GE:map[highestBid:22 last:24]]

正如我所说,我是GO的新手,我能得到的帮助和解释将非常受欢迎

2 个答案:

答案 0 :(得分:0)

你已经到了中途,你只需要在你的结构中解组,然后按一下数据:

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)
}

这里的工作示例:https://play.golang.org/p/iagx8RWFfx_k

答案 1 :(得分:0)

如果市场片段是一个对您有用的数据结构,您可能希望对其进行别名并实施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{}
    // Unmarshal directly into a []Market alias
    _ = json.Unmarshal(jsonBytes, &ml)

    fmt.Printf("%+v\n", ml)
}

Runnable version here