为了账号安全,请及时绑定邮箱和手机立即绑定

如何将具有嵌入式结构的结构展平为 json

如何将具有嵌入式结构的结构展平为 json

Go
萧十郎 2023-02-21 13:01:07
给定以下结构类型,StructA并且StructB嵌入在CompleteStructtype StructA struct {    A int `json:"a_a"`    B int `json:"a_b"`    C int `json:"a_c"`}type StructB struct {    A int `json:"b_a"`    B int `json:"b_b"`}type CompleteStruct struct {    Name string `json:"name"`    StructA    StructB}这s是一个新结构。s := CompleteStruct{Name: "Example",    StructA: StructA{        A: 1,         B: 2,         C: 3,    },    StructB: StructB{        A: 4,        B: 5,    },}你如何转化s为下面的json。[  {    "name": "Example",    "field": "a_a",    "value": 1  },  {    "name": "Example",    "field": "a_b",    "value": 2  },  {    "name": "Example",    "field": "a_c",    "value": 3  },  {    "name": "Example",    "field": "b_a",    "value": 4  },  {    "name": "Example",    "field": "b_b",    "value": 5  }]注意:实际上,CompleteStruct将包含 10 个或更多嵌入式结构,每个嵌入式结构将包含 10 个或更多字段。所以我想要一个不需要单独输入每个字段的解决方案,我认为这将需要使用反射
查看完整描述

2 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

不反思是解决不了的。简单示例:


func (u *CompleteStruct) MarshalJSON() ([]byte, error) {

    type Result struct {

        Name  string `json:"name"`

        Field string `json:"field"`

        Value any    `json:"value"`

    }

    

    var res []Result

    val := reflect.ValueOf(u).Elem()

    for i := 0; i < val.NumField(); i++ {

        field := val.Field(i)

        switch field.Kind() {

        case reflect.Struct:

            for i := 0; i < field.NumField(); i++ {

                tp := field.Type().Field(i)

                field := field.Field(i)

                res = append(res, Result{

                    Name:  u.Name,

                    Field: tp.Tag.Get("json"),

                    Value: field.Interface(),

                })

            }

        }

    }

    return json.Marshal(res)

}


查看完整回答
反对 回复 2023-02-21
?
烙印99

TA贡献1829条经验 获得超13个赞

这应该给你你想要的结构:


package main


import (

    "encoding/json"

    "os"

    "reflect"

)


type StructA struct {

    A int `json:"a_a"`

    B int `json:"a_b"`

    C int `json:"a_c"`

}

type StructB struct {

    A int `json:"b_a"`

    B int `json:"b_b"`

}


type CompleteStruct struct {

    Name string `json:"name"`

    StructA

    StructB

}


func main() {

    s := CompleteStruct{Name: "Example",

        StructA: StructA{

            A: 1,

            B: 2,

            C: 3,

        },

        StructB: StructB{

            A: 4,

            B: 5,

        },

    }


    flat(s)


    json.NewEncoder(os.Stdout).Encode(results)

}


type resp struct {

    Name  string `json:"name"`

    Field string `json:"field"`

    Value any    `json:"value"`

}


var globalName string

var results []resp


func flat(s interface{}) {

    st := reflect.TypeOf(s)

    for i := 0; i < st.NumField(); i++ {

        field := st.Field(i)

        if field.Type.Kind() == reflect.Struct {

            flat(reflect.ValueOf(s).Field(i).Interface())

        } else {

            name := field.Tag.Get("json")

            if name == "name" {

                globalName = reflect.ValueOf(s).Field(i).String()

                continue

            }

            results = append(results, resp{Name: globalName, Field: name, Value: reflect.ValueOf(s).Field(i).Interface()})

        }

    }

}

go run ./main.go | jq '.'


查看完整回答
反对 回复 2023-02-21
  • 2 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号