递归地展平地图golang

使用下面的 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"

    },

}

我认为处决不是按顺序执行的。如果我错了,请纠正我。


慕容708150
浏览 84回答 1
1回答

拉风的咖菲猫

现在看看你的循环:var key stringvar 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        }    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go