はじめに
似たような内容の記事はあったのですが、バージョンが変わったせいかうまく動かなくて苦労したので記事にしました。
JSONを使うバージョン
var result map[string]interface{}
indirect, _ := json.Marshal(data)
json.Unmarshal(indirect, &result)
// 値がなかったら、キーの削除
for key, value := range result {
if value == nil {
delete(result, key)
}
}
これだと、time.Time型がStringになってしまい、僕の用途には合いませんでした。。
reflectを使うバージョン
result := make(map[string]interface{})
v := reflect.Indirect(reflect.ValueOf(data))
t := v.Type()
for i := 0; i < t.NumField(); i++ {
ft := t.Field(i)
fv := v.FieldByName(ft.Name)
// nullの場合のみセット
if !fv.IsNil() {
result[ft.Name] = reflect.Indirect(reflect.ValueOf(fv.Interface()))
}
}
reflect.Indirect
は、fv.Interface()
の値がポインタだった場合にそれを外す処理です。
ポインタのままmapに入れたい!って方にはいらないです。
参考文献
https://qiita.com/keitaj/items/440a50a53c8980ee338f
https://qiita.com/chimatter/items/b0879401d6666589ab71
https://qiita.com/nirasan/items/b6b89f8c61c35b563e8c