简体   繁体   English

在map [string] interface {}的值上键入switch到[] map [string] interface {}

[英]Type switch to []map[string]interface{} on the value of map[string]interface{}

Problem 问题

I'm facing the issue to remove not required arrays from an json object eg. 我面临着从json对象中删除不需要的数组的问题。 arrays with only one element which is not an object or array. 仅包含一个不是对象或数组的元素的数组。 (No arrays as root of the input) (没有数组作为输入的根)

Example

In: 在:

{"name": [{ "inner": ["test"] }]}

Wanted Out: 想要:

{"name": [{ "inner": "test" }]}

Approach 途径

I started with a simple type switch on the values of a parsed map[string]interface{} and recognized that it wont switch to the case []map[string]interface{} . 我从对解析的map[string]interface{}的值进行简单的类型切换开始,意识到它不会切换到case []map[string]interface{} (Given example) (举个例子)

So here is the implementation I came up with. 所以这是我想出的实现。 It works for most of the scenarios but not for inner Objects within an array yet. 它适用于大多数情况,但不适用于数组中的内部对象。

type jsonMap map[string]interface{}
type jsonMapList []map[string]interface{}

m := jsonMap{}

err := json.Unmarshal(s, &m)
if err != nil {
    panic(err)
}

res := removeFromObject(m)

bytes, err := json.Marshal(res)
if err != nil {
    panic(err)
}
result := string(bytes)
log.Infof("Parse Result: %s", result)

func removeFromObject(in jsonMap) jsonMap {
    res := jsonMap{}

    for k, v := range in {
        switch value := v.(type) {
        case jsonMap:
            res[k] = removeFromObject(value)
        case jsonMapList:
            list := []jsonMap{}
            for _, entry := range value {
                list = append(list, removeFromObject(entry))
            }
            res[k] = list
        case []interface{}:
            if len(value) == 1 {
                res[k] = value[0]
            } else {
                res[k] = value
            }
        default:
            res[k] = value
        }
    }

    return res
}

Question

How do I switch case to an object array, so that I can recursively resolve the objects within that array too? 如何将大小写切换到对象数组,以便也可以递归地解析该数组中的对象?

You can use this function to remove the undesired arrays. 您可以使用此功能删除不需要的数组。

func removearr(x interface{}) interface{} {
    switch val := x.(type) {
    case map[string]interface{}:
        for k, v := range val {
            val[k] = removearr(v)
        }
        return val
    case []interface{}:
        if len(val) == 1 {
            // remove array only if the value is not an object
            if _, ok := val[0].(map[string]interface{}); !ok {
                return removearr(val[0])
            }
        }

        for i, v := range val {
            val[i] = removearr(v)
        }
        return val
    default:
        return x
    }
}

https://play.golang.com/p/mwo7Y2rJ_lc https://play.golang.com/p/mwo7Y2rJ_lc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM