Reputation: 300
I have to convert map of structure to slice of structure in Golang, i.e. source to target structure specified below.
// Source
var source map[string]Category
type Category struct {
A int
SubCategory map[string]SubCategory
}
type SubCategory struct {
B int
C string
}
// Target
var target []OldCategory
type OldCategory struct {
OldA int `mapstructure:"A"`
OldSubCategory []OldSubCategory
}
type OldSubCategory struct {
OldB int `mapstructure:"B"`
OldC string `mapstructure:"C"`
}
I am referring mapstrucuture package ("github.com/mitchellh/mapstructure"). One way to convert from source to target is to iterate on all the SubCategory and then Category in source instance and use mapstructure.Decode() to convert each one individually.
Is there a direct way using mapstrucuture package, wherein I create a custom decoder hook using NewDecoder and DecoderConfig.DecodeHook, and whenever I encounter source as a map of structure and target as a slice of structure, I handle it in the DecodeHookFunc function.
Relevant documentation of mapstructure https://godoc.org/github.com/mitchellh/mapstructure#NewDecoder
Upvotes: 1
Views: 3255
Reputation: 46
you could do it using mapstructure decoder hooks, write custom logic inside the decoder hook , to do your job. But there is no standard lib function to do your job.
Example:
dc := &mapstructure.DecoderConfig{Result: target, DecodeHook: customHook}
ms, err := mapstructure.NewDecoder(dc)
if err != nil {
return err
}
err = ms.Decode(source)
if err != nil {
return err
}
func customHook(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
if f.Kind() == reflect.Int && t.Kind() == reflect.Bool {
var result bool
if data == 1 {
result = true
}
return result, nil
}
So you could technically decode anything to anything using custom hooks as long it has your custom logic.
Upvotes: 2
Reputation: 42476
In Go is there a way to convert map of structure to slice of structure
No, there is no language construct or syntactical sugar for this.
Upvotes: -1
Reputation: 11
Use nested for loops:
for _, c := range source {
oc := OldCategory{OldA: c.A}
for _, sc := range c.SubCategory {
oc.OldSubCategory = append(oc.OldSubCategory, OldSubCategory{OldB: sc.B, OldC: sc.C})
}
target = append(target, oc)
}
Upvotes: 1