使用反射(reflect)将所有属性转换为小写或大写?

huangapple go评论95阅读模式
英文:

Make all properties lower case or upper case using reflect?

问题

我正在从客户端接收未知的 JSON 数据,并将其解析为接口类型:

var f interface{}
err := json.Unmarshal(b, &f)

如何将 f 中的所有键转换为小写键?我需要将这个 f 保存到 MongoDB,并且我需要进行一些查询,但我希望避免错误,以防有人发送相同的 JSON 数据但使用了大写键。

英文:

I am receiving unknown json from client and I parse to interface like

var f interface{}
err := json.Unmarshal(b, &f)

How to make all keys in f to be lower keys ?
I have to save this f to mongo and I need to make some queries but I want to avoid mistake if somebody send uppercase same json.

答案1

得分: 5

这是一种方法:

var v any
err := json.Unmarshal(b, &v)
v = lower(v)

其中lower函数定义如下:

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
    }
}

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

playground

如果你知道你正在处理的对象没有嵌套(对象字段不包含数组或其他对象),那么你可以将上述lower函数中的map case内联:

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
英文:

Here's one way to do it:

var v any
err := json.Unmarshal(b, &v)
v = lower(v)

where lower is:

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
	}
}

The lower function calls itself recursively to handle key conversion in nested JSON objects and arrays.

playground

If you know that you are working with an object without nesting (the object fields do not contain arrays or other objects), then you can inline the map case from the lower function above:

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

答案2

得分: 3

将会是 map[string]interface{},所以遍历它并简单地将键转换为小写。

var f map[string]interface{}
...

converted := make(map[string]interface{}, len(f))
for k, v := range f {
    converted[strings.ToLower(k)] = v
}

翻译结果:

var f map[string]interface{}
...

converted := make(map[string]interface{}, len(f))
for k, v := range f {
    converted[strings.ToLower(k)] = v
}
英文:

It will be map[string]interface{} so go over it and simply convert keys to lowercase.

var f map[string]interface{}
...

converted := make(map[string]interface{}, len(f))
for k, v := range f {
    converted[strings.ToLower(k)] = v
}

huangapple
  • 本文由 发表于 2015年7月9日 23:24:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/31321805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定