Last active
August 7, 2021 19:12
-
-
Save pmn/5374494 to your computer and use it in GitHub Desktop.
Convert an interface{} containing a slice of structs to [][]string (used in CSV serialization) [golang reflection example] Runnable example here: http://play.golang.org/p/ZSJRxkpFs9
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Convert an interface{} containing a slice of structs into [][]string. | |
func recordize(input interface{}) [][]string { | |
var records [][]string | |
var header []string // The first record in records will contain the names of the fields | |
object := reflect.ValueOf(input) | |
// The first record in the records slice should contain headers / field names | |
if object.Len() > 0 { | |
first := object.Index(0) | |
typ := first.Type() | |
for i := 0; i < first.NumField(); i++ { | |
header = append(header, typ.Field(i).Name) | |
} | |
records = append(records, header) | |
} | |
// Make a slice of objects to iterate through & populate the string slice | |
var items []interface{} | |
for i := 0; i < object.Len(); i++ { | |
items = append(items, object.Index(i).Interface()) | |
} | |
// Populate the rest of the items into <records> | |
for _, v := range items { | |
item := reflect.ValueOf(v) | |
var record []string | |
for i := 0; i < item.NumField(); i++ { | |
itm := item.Field(i).Interface() | |
record = append(record, fmt.Sprintf("%v", itm)) | |
} | |
records = append(records, record) | |
} | |
return records | |
} |
if it can help other people like it was for me
package convert
import (
"reflect"
)
type PairKeyValue struct {
Id int
Key string
Value int
}
// Convert an interface{} containing a slice of structs to []PairKeyValue
func ConvertInterface_A(input interface{}) []PairKeyValue {
var records []PairKeyValue
object := reflect.ValueOf(input)
// Make a slice of objects to iterate through and populate the string slice
var items []interface{}
for i := 0; i < object.Len(); i++ {
items = append(items, object.Index(i).Interface())
}
// Populate the rest of the items into <records>
for _, v := range items {
item := reflect.ValueOf(v)
var record PairKeyValue
itm0 := item.Field(0).Interface()
itm1 := item.Field(1).Interface()
itm2 := item.Field(2).Interface()
record.Id = itm0.(int)
record.Key = itm1.(string)
record.Value = itm2.(int)
records = append(records, record)
}
return records
}
// Convert an interface{} containing a struct to PairKeyValue
func ConvertInterface_B(input interface{}) PairKeyValue {
var record PairKeyValue
item := reflect.ValueOf(input)
// Populate the rest of the items into <records>
itm0 := item.Field(0).Interface()
itm1 := item.Field(1).Interface()
itm2 := item.Field(2).Interface()
record.Id = itm0.(int)
record.Key = itm1.(string)
record.Value = itm2.(int)
return record
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
have a set of structs which have fields of two types first is uint and second is slice of structs. In the method below am attempting to set up anonymous recursion through the various sub structs.
func HandleMsg() {
var msg = CreateK001Message()
t := reflect.ValueOf(&msg).Elem()
typeOfT := t.Type()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tag := typeOfT.Field(i).Tag
switch f.Kind() {
case reflect.Uint:
fmt.Printf("%d: %s %s = %v %+v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface(), tag)
case reflect.Slice:
fmt.Printf("%d: %s %s = %v %+v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface(), tag)
var res = recordize(f.Interface())
var nw []string
for j := 0; j < len(res[0]); j++ {
var field = res[0][j] + " = " + res[1][j]
nw = append(nw, field)
}
//handleSliceField(nw)
default:
}
}
}
In the Slice section I have used your method above to build a representation of the first []subsstruct but of course it is no longer a struct and I cannot process it as one.
From the f.Interface() I can get a string that is a json representation of this first level.
Is there any way to create an anonymous struct using your work or the string from f.Interface?