微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从未编组的数据中准备一个 json 对象

如何解决从未编组的数据中准备一个 json 对象

我有这样的 json 数据:

json: {"opt1":200,"opt3":"1","opt4":"13","opt5":null,"products":[{"product_id":1,"price":100,"variant_id":100},{"product_id":1,"variant_id":null}]}

我已经使用

构建了它
type Products struct {
    Product_id int
    Price json.Number
    Variant_id int
}


type Pdata struct {
    Products []Products `json:"products"`
}

然后我使用解组

jsonb := []byte(jsonVal)
    var data Pdata
    err := json.Unmarshal(jsonb,&data)
    if err != nil {
        fmt.Println(err)
        return
    }

得到类似的输出

{[{1 100 100} {2 100 0}]}

现在我需要将这些数据转换成这样的 json 对象

{"purchased_products": [{"product_id": 1,"price": 1200,"variation_id": 100},{"product_id": 2,"price": 100,"variation_id": null}]}

之后,我需要将它分配给“json”

var d = map[string]string{
    "json":        jsonVal,"created_at":  time.Now().Format("2006-01-02 15:04:05"),"updated_at":  time.Now().Format("2006-01-02 15:04:05"),}

我该怎么做?

解决方法

创建一个类型(例如:PurchaseProducts)如下。

type PurchasedProducts struct {
    Products []Products `json:"purchased_products"`
}

并初始化一个 PurchasedProducts 类型变量,并将解组的产品分配给 Purchased 产品,如下所示。

    pProducts := PurchasedProducts{Products: data.Products}
    jsonByte,err := json.Marshal(pProducts)
    if err != nil {
        fmt.Println(err)
        return
    }

然后将该 []byte 数组转换为字符串并将其分配给地图,如下所示。

    var d = map[string]string{
        "json":        string(jsonByte),"created_at":  time.Now().Format("2006-01-02 15:04:05"),"updated_at":  time.Now().Format("2006-01-02 15:04:05"),}

您可以运行并查看完整代码 here

,

对于可为空的字段,您可以使用指针,例如,如果 variant_id json 字段可以是整数或 json null,并且您希望保留该信息,那么您可以更改 {{ 1}} 到 Variant_id int

Variant_id *int

要在 unmarshal 和 marshal 之间更改 json 字段名称,您可以声明第二个 type Product struct { Product_id int `json:"product_id"` Price json.Number `json:"price"` Variant_id *int `json:"variant_id"` } 结构,其字段与原始字段相同,但带有定义所需字段名称的结构标记,然后,如果结构是,则在所有其他方面,您可以在它们之间进行转换。

Products

然后,如果 type Product struct { Product_id int `json:"product_id"` Price json.Number `json:"price"` Variant_id int `json:"variant_id"` } type PurchasedProduct struct { Product_id int `json:"product_id"` Price json.Number `json:"price"` Variant_id int `json:"variation_id"` // here variant_id becomes variation_id } 的类型为 p,您可以简单地将其转换为 Product,如下所示:

PurchasedProduct

要将转换卸载到封送处理过程,您可以让原始类型实现 pp := PurchasedProduct(p) 接口并在那里进行转换。

json.Marshaler

通过以上操作,您可以执行以下操作:

func (p Product) MarshalJSON() ([]byte,error) {
    type P struct {
        Product_id int         `json:"product_id"`
        Price      json.Number `json:"price"`
        Variant_id *int        `json:"variation_id"`
    }
    return json.Marshal(P(p))
}

https://play.golang.org/p/0gnrjgUslza

,

简单地定义另外两个结构体来为第二个 JSON 对象建模:

type Pdata2 struct {
    PurchasedProducts []Product2
}

type Product2 struct {
    Product_id    int
    Price         json.Number
    Variation_id  *int // pointer to int
}

Variation_id 字段是 *int 类型,因为您所需的输出 JSON 显示 "variation_id": null。如果您将该字段声明为简单的 int,则其零值将被封送到 0

然后使用之前的值初始化这些结构:

func main() {
    data2 := Pdata2{
        PurchasedProducts: make([]Product2,len(data.Products)),}

    for i,p := range data.Products {
        data2.PurchasedProducts[i] = Product2{
            Product_id:   p.Product_id,Price:        p.Price,Variation_id: nullableInt(p.Variant_id),}
    }

    b,err := json.Marshal(data2)
    if err != nil {
        // ... handle error
    }
    var d = map[string]string{
        "json": string(b),// ...
    }
    fmt.Println(d)
}

func nullableInt(n int) *int {
    if n == 0 {
        return nil
    }
    return &n
}

游乐场:https://play.golang.org/p/xhsmHNBjRKN

,

给你。 假设是:

  • Product 是一个可能要复杂得多的模型,因此它具有专用的结构。因此,从 Product 到 OutputProduct 的转换可以单独进行单元测试。
  • 它是一次性使用的应用程序,而不是公开 API 的应用程序的一部分。否则它应该被适当地分成层,输出应该写成一个结构。
package main

import (
    "encoding/json"
    "log"
    "os"
    "time"
)

type (
    Product struct {
        ProductID int `json:"product_id"`
        VariantID int `json:"variant_id"`
        Price     json.Number
    }
    Products []Product

    OutputProduct struct {
        ProductID int `json:"product_id"`
        VariantID int `json:"variation_id"`
        Price     json.Number
    }
)

func (p Product) ToOutputProduct() OutputProduct {
    return OutputProduct{
        ProductID: p.ProductID,VariantID: p.VariantID,Price:     p.Price,}
}

func (p Products) ToOutputProducts() []OutputProduct {
    outputProducts := make([]OutputProduct,len(p))
    for i := 0; i < len(p); i++ {
        outputProducts[i] = p[i].ToOutputProduct()
    }
    return outputProducts
}

func main() {
    var inputJSON = `{"opt1":200,"opt3":"1","opt4":"13","opt5":null,"products":[{"product_id":1,"price":100,"variant_id":100},{"product_id":1,"variant_id":null}]}`

    var parsedInput struct {
        Products Products
    }
    if err := json.Unmarshal([]byte(inputJSON),&parsedInput); err != nil {
        log.Fatal(err)
    }

    var output = map[string]interface{}{
        "json":       map[string][]OutputProduct{
            "purchased_products": parsedInput.Products.ToOutputProducts(),},"created_at": time.Now().Format("2006-01-02 15:04:05"),"updated_at": time.Now().Format("2006-01-02 15:04:05"),}
    encoder := json.NewEncoder(os.Stdout)
    encoder.SetIndent(" ","  ")
    if err := encoder.Encode(output); err != nil {
        log.Fatal(err)
    }
}
,

基于评论中的建议:

package main

import (
    "encoding/json"
    "log"
    "time"
)

type Products struct {
    Product_id int `json:"product_id"`
    Price      int `json:"price"`
    Variant_id int `json:"variant_id"`
}

type ProductData struct {
    Products []Products `json:"products"`
}

type Response struct {
    Json      json.RawMessage `json:"json"`
    CreatedAt string          `json:"created_at"`
    UpdatedAt string          `json:"updated_at"`
}

func main() {
    productJson := `{
        "opt1": 200,"opt3": "1","opt4": "13","opt5": null,"products": [
            { "product_id": 1,"price": 100,"variant_id": 100 },{ "product_id": 1,"variant_id": null }
        ]
    }`

    productData := &ProductData{}
    err := json.Unmarshal([]byte(productJson),&productData)
    if err != nil {
        panic(err)
    }

    b,err := json.Marshal(map[string]interface{}{"purchased_products": productData.Products})
    if err != nil {
        panic(err)
    }

    d := &Response{
        Json:      b,CreatedAt: time.Now().Format("2006-01-02 15:04:05"),UpdatedAt: time.Now().Format("2006-01-02 15:04:05"),}

    out,err := json.Marshal(d)
    if err != nil {
        panic(err)
    }

    log.Println(string(out))
}

输出:

2009/11/10 23:00:00 {"json":{"purchased_products":[{"product_id":1,"variant_id":0}]},"created_at":"2009-11-10 23:00:00","updated_at":"2009-11-10 23:00:00"}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。