使用 Reflect 使所有属性小写或大写?

Bla*_*ama 0 go

我从客户端收到未知的 json,我解析为接口,如

var f interface{}
err := json.Unmarshal(b, &f)
Run Code Online (Sandbox Code Playgroud)

如何让f中的所有键都变成下键?我必须将此 f 保存到 mongo,并且需要进行一些查询,但如果有人发送大写的相同 json,我想避免错误。

Cer*_*món 5

这是一种方法:

var v any
err := json.Unmarshal(b, &v)
v = lower(v)
Run Code Online (Sandbox Code Playgroud)

其中较低的是:

func lower(v any) any {
    switch v := v.(type) {
    case []any:
        lv := make([]any, len(v))
        for i := range v {
            lv[i] = lower(v[i])
        }
        return lv
    case map[string]any:
        lv := make(map[string]any, len(v))
        for mk, mv := range v {
            lv[strings.ToLower(mk)] = mv
        }
        return lv
    default:
        return v
    }
}
Run Code Online (Sandbox Code Playgroud)

lower函数递归调用自身来处理嵌套 JSON 对象和数组中的键转换。

操场

如果您知道正在使用没有嵌套的对象(对象字段不包含数组或其他对象),那么您可以从lower上面的函数内联映射案例:

var v map[string]any
err := json.Unmarshal(b, &v)
lv := make(map[string]any, len(v))
for mk, mv := range v {
    lv[strings.ToLower(mk)] = mv
}
v = lv
Run Code Online (Sandbox Code Playgroud)