首页 > 解决方案 > 解组时如何合并/修改 json?

问题描述

我有一些像这样的示例 json:

"payment_details": {
   "acc_number": "",
   "sort_code_1": "00",
   "sort_code_2": "11",
   "sort_code_3": "22"
},

我像这样解组

i := &MyStruct{}
return i, json.Unmarshal(theJson, &i)

我希望 MyStruct 看起来像这样

type MyStruct struct {
    AccNumber *string `json:"acc_number"`
    SortCode *string `json:"sort_code"`
}

但是我想将单独的排序代码字段合并为一个,以便最终 MyStruct 看起来像这样

type MyStruct struct {
    AccNumber *string `json:"acc_number"` 
    SortCode *string `json:"sort_code"` // "00-11-22"
}

在解组时有没有聪明的方法来做到这一点?

标签: go

解决方案


You can write your own unmarshaller. The easiest way is to use a secondary struct that represents the json form. (Complete working example on the playground)

type MyStruct struct {
    AccNumber *string
    SortCode *string
}

type MyStruct_JSON struct {
    AccNumber *string `json:"acc_number"`
    SortCode1 string `json:"sort_code_1"`
    SortCode2 string `json:"sort_code_2"`
    SortCode3 string `json:"sort_code_3"`
}

func (ms *MyStruct) UnmarshalJSON(d []byte) error {
    var msj MyStruct_JSON
    if err := json.Unmarshal(d, &msj); err != nil {
        return err
    }
    // TODO: error checking for sort codes to check they're well-formed
    sortCode := msj.SortCode1 + "-" + msj.SortCode2 + "-" + msj.SortCode3
    *ms = MyStruct{
        AccNumber: msj.AccNumber,
        SortCode: &sortCode,
    }
    return nil
}

Note: it's not clear if you need all the pointers like *string or whether you can just use string. The latter is generally easy to use (and definitely will help you avoid nil-pointer dereferences), but has the potential downside of not being able to distinguish empty values from missing values. I use plain string for SortCode[1,2,3] because it looks like they have to be two-digit codes for them to be valid, so empty strings or missing fields are both errors.


推荐阅读