I am trying to flatten a dynamic value in Go into a slice of key value pairs. So I define a struct as :
type KeyValuePair struct {
key string
value interface{}
}
For simple values like x = 10
, the function should return []KeyValuePair{"x", 10}
,
for y = "hello"
, it should return []KeyValuePair{"y", "hello"}
. For structs like x = {A: 10, B: "test"}
, it should return []KeyValuePair{{"A", 10}, {"B", "test"}}
.
And it should handle nested structs like x = {A: 10, B: {C: true}}
I tried the following using recursion but it's far from what I want even for built-in types like int
.
func flattenObject(o interface{}) []KeyValuePair {
var result []KeyValuePair
t := reflect.TypeOf(o)
switch t.Kind() {
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int32, reflect.Int64, reflect.String:
//v := reflect.ValueOf(t)
result = append(result, KeyValuePair{key: fmt.Sprintf("%s", o), value: o})
case reflect.Struct:
v := reflect.ValueOf(t)
for i := 0; i < v.NumField(); i++ {
kv := KeyValuePair{key: t.Field(i).Name, value: v.Field(i)}
result = append(result, flattenObject(kv)...)
}
case reflect.Slice:
v := reflect.ValueOf(t)
if !v.IsNil() {
for i := 0; i < v.Len(); i++ {
result = append(result, flattenObject(v.Index(i))...)
}
}
}
return result
}