使用反射使所有属性为小写还是大写?

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.

Here's one way to do it:

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

where lower is:

func lower(f interface{}) interface{} {
  switch f := f.(type) {
  case []interface{}:
    for i := range f {
        f[i] = lower(f[i])
    }
    return f
  case map[string]interface{}:
    lf := make(map[string]interface{}, len(f))
    for k, v := range f {
        lf[strings.ToLower(k)] = lower(v)
    }
    return lf
  default:
    return f
  }
}

The function lower is recursive to handle key conversion for nested JSON objects.

playground

If you know that you are working with an object without nesting, then you can inline the map case from lower:

var f map[string]interface{}
err := json.Unmarshal(b, &f)
lf := make(map[string]interface{}, len(f))
for k, v := range f {
    lf[strings.ToLower(k)] = v
}
f = lf

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
}