将多个JSON字段解码为一个字段在Golang中的实现

huangapple go评论88阅读模式
英文:

Decode Multiple JSON Fields into one in Golang

问题

我正在使用一个 API,令人沮丧的是,相同的值在不同的情况下具有不同的字段名称。例如,一个 API 响应可能如下所示:

{
  "PersonFirstName": "John",
  "PersonLastName": "Smith"
}

而另一个 API 响应可能如下所示:

{
  "FirstNm": "John",
  "LastNm": "Smith"
}

假设我有一个结构体,我想将 JSON 解码为该结构体。它可能如下所示:

type Name struct {
    FirstName string
    LastName  string
}

通常情况下,如果 API 是一致的,我只需要这样做:

type Name struct {
    FirstName string `json:"PersonFirstName"`
    LastName  string `json:"PersonLastName"`
}

然后使用内置的 JSON 解码器 来构建结构体。然而,当存在多个字段值时,我不知道一种简洁的方法将 JSON 解码为结构体。有什么想法吗?

英文:

I am working with an API that, frustratingly, has field names that vary for the same value. For example, one API response could look like this:

<!-- language: lang-js -->

{
  &quot;PersonFirstName&quot;: &quot;John&quot;,
  &quot;PersonLastName&quot;: &quot;Smith&quot;
}

<!-- end snippet -->

while another looks like this:

<!-- language: lang-js -->

{
  &quot;FirstNm&quot;: &quot;John&quot;,
  &quot;LastNm&quot;: &quot;Smith&quot;
}

<!-- end snippet -->
Suppose then I had a struct which I would like to decode my JSON to. It might look like this:

type Name struct {
    FirstName string
    LastName  string
}

Typically I would just be able to do the following if the API was consistent:

type Name struct {
    FirstName string `json:&quot;PersonFirstName&quot;`
    LastName  string `json:&quot;PersonLastName&quot;`
}

and then use the built-in JSON decoder to build the struct. When there are multiple field values like this, though, I don't know a clean way to decode the JSON into a struct. Any ideas?

答案1

得分: 1

使用map[string]string。这是Go中的等效结构。你将它们看作结构体,因为它们是对象,这是合理的做法。每当你看到属性名称有不同的值时,这就是你需要在Go中使用map来表示数据的线索。

如果你需要进行规范化/静态类型实现一个名为NameFromMap(data map[string]string) (*Name, error)的辅助函数。在其中使用switch语句来处理键可能具有的各种值。

编辑:你也可以为你的类型实现UnmarshalJSON方法。你只需在其中加入我提到的switch语句。这里有一个示例:https://stackoverflow.com/questions/23798283/golang-unmarshal-json

我个人更喜欢我之前提到的第一种方法,因为这样可以明确地调用一个抽象的步骤。

英文:

Use a map[string]string. That is the equivalent structure in Go. You're looking at those as being structs because their objects, and that's the sensible thing to do. Anytime you see different values for the property names that's your clue that a map is the only reasonable representation of the data in Go.

If you need to normalize/have static typing implement a helper function called NameFromMap(data map[string]string) (*Name, error). Put the switch statement in there to deal with the various values you can have for the keys.

Edit: you could also implement UnmarshalJSON for your type. You would just put this switch statement I allude to there. Here's an example; https://stackoverflow.com/questions/23798283/golang-unmarshal-json

I personally prefer the first method I said because this sort of abstracts a step that I'd rather see called explicitly.

huangapple
  • 本文由 发表于 2015年6月26日 06:48:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/31062088.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定