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

使用高浪结构更新嵌套字段

使用高浪结构更新嵌套字段

Go
小唯快跑啊 2022-10-04 19:14:56
我遇到了使用 golang 更新结构字段的问题正如 var 名称所建议的那样,某些当前配置字段应使用请求的配置进行更新     currentConfig:=`     {         "field_one": "value",         "data": {             "field_two": [                 "data1",                 "data2"             ],             "field_three": "check",             "field_four": 12         },        "field_five": [                 "data1",                 "data2"             ],        "data2": {            "field_six":{                "field_seven": 100            }        }     }`              updateRequest:=`     {         "data": {             "field_three": "updated check" //ignore if same value exist (field_three exists in current config)         },        "field_five": ["data3"],    // append to current config        "data2": {            "field_six":{                "field_eight": 300  // add value if doesnt exist to current            }        }     }`func main() {    config := make(map[string]interface{})    err := json.Unmarshal([]byte(currentConfig), &config)    if err != nil {        panic(err)    }    updateFields := make(map[string]interface{})    err1 := json.Unmarshal([]byte(updateRequest), &updateFields)    if err1 != nil {        panic(err1)    }     fmt.Println(config)    updateFields = ParseJsonMap(updateFields, config)    fmt.Println(updateFields)}func ParseJsonMap(aMap map[string]interface{}, finalMap map[string]interface{}) map[string]interface{} {    parseMap("", aMap, &finalMap)    return finalMap}只是想知道这是否受支持,如果是,您可以帮助我,以及是否存在更好的方法
查看完整描述

1 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

您似乎正在尝试将一张地图叠加到另一张地图上。如果您不想在不更改现有地图的情况下应用此类更新,这将变得复杂。因此,将这两个步骤分开可能会更容易:

  • 复制map[string]interface{}

  • 将一个叠加在另一个之上map[string]interface{}

func CopyMap(m map[string]interface{}) map[string]interface{} {

    cp := make(map[string]interface{})

    for k, v := range m {

        vm, ok := v.(map[string]interface{})

        if ok {

            cp[k] = CopyMap(vm)

        } else {

            cp[k] = v

        }

    }

    return cp

}

func overlay(dst, src map[string]interface{}) error {

    for k, v := range src {


        if _, ok := dst[k]; !ok {

            dst[k] = v // easy case - dst key does not exist

            continue

        }


        d, ok1 := dst[k].(map[string]interface{})

        s, ok2 := src[k].(map[string]interface{})


        if ok1 && ok2 {

            overlay(d, s) // merge case

        } else if !ok1 && !ok2 {

            dst[k] = v // non-map - so simple assignment/reassignment

        } else {

            return fmt.Errorf("incompatible update types") // map to non-map or vice-versa

        }


    }

    return nil

}

使用:


err := json.Unmarshal([]byte(currentConfig), &config) // check err

err = json.Unmarshal([]byte(updateRequest), &updateFields) // check err

newconfig = CopyMap(config)

err = overlay(newconfig, updateFields) // check err

https://play.golang.org/p/RZPbkv19ChL


输出:


    config : map[data:map[field_four:12 field_three:check field_two:[data1 data2]] data2:map[field_six:map[field_eight:200 field_seven:100]] field_five:[data1 data2] field_one:value]

    update : map[data:map[field_three:check changed] data2:map[field_six:map[field_eight:300]] field_five:[data1]]

 newconfig : map[data:map[field_four:12 field_three:check changed field_two:[data1 data2]] data2:map[field_six:map[field_eight:300 field_seven:100]] field_five:[data1] field_one:value]

更新:要处理 JSON 数组的追加而不是替换,请执行以下操作:


func overlay2(dst, src map[string]interface{}) error {

    for k, v := range src {


        if _, ok := dst[k]; !ok {

            dst[k] = v // easy case - dst key does not exist

            continue

        }


        dm, ok1 := dst[k].(map[string]interface{})

        sm, ok2 := src[k].(map[string]interface{})


        if ok1 && ok2 {

            overlay2(dm, sm) // merge case

            continue

        }


        ds, ok1 := dst[k].([]interface{})

        ss, ok2 := src[k].([]interface{})


        if ok1 && ok2 {

            dst[k] = append(ds, ss...) // JSON array case

            continue

        }


        return fmt.Errorf("unhandled type/update")


    }

    return nil

}

https://play.golang.org/p/i-0yXMcqU7Z


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 89 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信