如何解决从未编组的数据中准备一个 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 举报,一经查实,本站将立刻删除。