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

递归地展平地图golang

递归地展平地图golang

Go
慕容708150 2022-12-19 18:15:24
使用下面的 json 我试图将其展平以便于访问。具有 2 个资源的示例在此结构中可以有 n 个"config": {    "type": "r1",    "properties": {        "p1": "10",        "p2": "10"    },    "connected": [        {            "type": "r3",            "properties": {              "p1": "10",              "p2": "10"            },            "connected": [                {}        },    ],}自定义奉承逻辑func keyValuePairs(m interface{}) map[string]interface{} {    kvs := make(map[string]interface{})    if reflect.ValueOf(m).Kind() == reflect.Map {        mp, ok := m.(map[string]interface{})        if ok {            var key string            var value interface{}            for k, v := range mp {                switch k {                case "type":                    key = v.(string)                case "properties":                    value = v                case "connected":                    if collection, ok := v.([]interface{}); ok {                        for _, c := range collection {                            for nk, nv := range keyValuePairs(c) {                                nnv, _ := nv.(map[string]interface{})                                _, ok := nnv["connectedTo"]                                if !ok {                                   nnv["connectedTo"] = key                                }                                kvs[nk] = nv                            }                        }                    }                default:                    for nk, nv := range keyValuePairs(v) {                        kvs[nk] = nv                    }                }            }            if key != "" {                kvs[key] = value            }        } else {            for k, v := range m.(map[string]interface{}) {                kvs[k] = v            }        }    }    return kvs}所需的输出有点波动,有些运行我得到了我需要的输出,有些执行“connectedTo”属性为空。{"r1": {        "p1": "10",        "p2": "10"    },"r3" : {        "connectedTo": "r1",        "p1": "10",        "p2": "10"    },}我认为处决不是按顺序执行的。如果我错了,请纠正我。
查看完整描述

1 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

现在看看你的循环:


var key string

var value interface{}

for k, v := range mp {

    switch k {

    case "type":

        key = v.(string)

    case "properties":

        value = v

    case "connected":

        if collection, ok := v.([]interface{}); ok {

            for _, c := range collection {

                for nk, nv := range keyValuePairs(c) {

                    nnv, _ := nv.(map[string]interface{})

                    _, ok := nnv["connectedTo"]

                    if !ok {

                       nnv["connectedTo"] = key

                    }

                    kvs[nk] = nv

                }

            }

        }

    default:

        for nk, nv := range keyValuePairs(v) {

            kvs[nk] = nv

        }

    }

}

您正在分支中使用key变量,但是达到和"connected"的顺序是不确定的(随机的)。"type""connected"


"type"分支是设置的key,但如果"connected"先到达,则为key空。


您不能依赖地图迭代顺序。


一个简单的解决方法是在循环之前"type"首先获取与first 关联的值并将其分配给key(您在"connected"分支中使用的值) 。


例如:


key, _ := mp["type"].(string)

value := mp["properties"]

// Now process other properties:

for k, v := range mp {

    switch k {

    case "type", "properties": // Already handled

    case "connected":

        if collection, ok := v.([]interface{}); ok {

            for _, c := range collection {

                for nk, nv := range keyValuePairs(c) {

                    nnv, _ := nv.(map[string]interface{})

                    _, ok := nnv["connectedTo"]

                    if !ok {

                       nnv["connectedTo"] = key

                    }

                    kvs[nk] = nv

                }

            }

        }

    default:

        for nk, nv := range keyValuePairs(v) {

            kvs[nk] = nv

        }

    }

}


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

添加回答

举报

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