【问题标题】:Golang consume json with dynamic relevant keysGolang 使用带有动态相关键的 json
【发布时间】:2018-07-02 20:37:39
【问题描述】:

我是 GO 新手,我正在尝试使用 GO 使用来自各种 API 的 json 数据,并将它们放在 struct 的其中之一中 像这样格式化数据

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

虽然我可以找到有关使用动态键消费的信息,但我发现的所有示例都将最外层的键视为任意且不相关的。我需要将其用作键值对,如下所示:

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

我了解使用接口映射,但我不知道如何将动态键映射到结构作为键:值对,如上。我的代码示例可以在 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)



}

就这样输出

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

正如我所说,我是 GO 新手,如果我能得到尽可能多的帮助和解释,我将不胜感激

【问题讨论】:

    标签: json go dynamic unmarshalling


    【解决方案1】:

    你已经完成了一半,你只需要解组到你的结构,然后稍微处理一下数据:

    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

    【讨论】:

    • 非常感谢,正如预期的那样,有人可以让它看起来如此简单!
    【解决方案2】:

    如果 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{}
        // Unmarshal directly into a []Market alias
        _ = json.Unmarshal(jsonBytes, &ml)
    
        fmt.Printf("%+v\n", ml)
    }
    

    Runnable version here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-13
      • 2018-05-24
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      • 2017-12-29
      • 2022-01-21
      • 2019-08-16
      相关资源
      最近更新 更多