【问题标题】:Multi-level Unmarshall JSON with changing key values具有更改键值的多级 Unmarshall JSON
【发布时间】:2020-08-30 05:14:46
【问题描述】:

我看过一些像 this one 这样的帖子,它们解决了在不同键上解组的问题。但是,当我有多个图层时,我似乎很难弄清楚如何去做。

这是我想要解组的内容:

{"chainlink":{"usd":3.75}} 但是chainlinkusd 可能不同。

我目前的做法是这样的:

type cryptoCurrency struct {
    Currency cryptoCurrencyResult `json: "chainlink,JPY,gold,apple"`
}

type cryptoCurrencyResult struct {
    Usd float64 `json: "usd,USDT,peso"`
}

(以上显然是错误的)

然后使用它们:

var crypto cryptoCurrency
json.Unmarshal(data, &crypto)

但同样,数据可能看起来像:

{"chainlink":{"usd":3.75}}
{"JPY":{"USDT":1000}}
{"gold":{"peso":100}}
{"apple":{"usd":1.35}}

目前关于 SO 的解决方案似乎是单级解组。

【问题讨论】:

  • 您可以为结构标记中的 JSON 字段提供一个名称。您也不能在标记命名空间和值之间包含空格(即json: "thing" 必须是json:"thing")。看来您在这里想要的是map,而不是struct
  • 如果你确定有一个二级映射,你可以解组成一个映射的映射。如果保证单级映射,您可以解组到map[string]interface{} 并检查,或使用json.RawMessage
  • 谢谢大家!这些可能是我的答案而不是 cmets。答案是 torek、Adrian 和 Tarun 的组合。我不知道你可以将它们解组为地图,所以我能够将它们解组为 map[string]map[string]float64

标签: go struct unmarshalling


【解决方案1】:

我的一些假设/建议:

  1. 您不应丢失有关加密货币类型的数据,即是否是链环、日元、黄金或苹果。
  2. 您可能还需要考虑货币,然后在程序中将所有内容转换为标准货币。 (我在我的解决方案中以美元为标准)
  3. 我还假设您的 JSON 结构仅限于您在示例中显示的内容。如果有更多的键,解决方案(当然)会有所改变。

您可以对结构使用自定义解组,如下所示:

type cryptoCurrency struct {
    Type       string
    PriceInUSD float64
}

func (c *cryptoCurrency) UnmarshalJSON(data []byte) error {
    var tmp map[string]map[string]float64
    json.Unmarshal(data, &tmp)
    for k, v := range tmp {
        c.Type = k
        switch {
        case v["usd"] != 0.0:
            c.PriceInUSD = v["usd"]
        case v["USDT"] != 0.0:
            // Convert into USD... same for peso
        }
    }
    return nil
}

这是go playground 中的工作示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 2018-12-03
    • 2019-11-23
    相关资源
    最近更新 更多