How do I turn an array of JSON objects into an array of structs with default values in Go? -


i'm working on go api can receive posts consisting of json array of objects. structure of post like:

[   {     "name":"las vegas",     "size":14   },   {     "valid": false,     "name":"buffalo",     "size":63   } ]   

let's have following struct:

type data {     valid    bool     name     string     size     float64 } 

i want create bunch of datas valid set true anytime it's not specified in json false. if doing single 1 use how specify default values when parsing json in go, doing unknown number of them thing i've been able come like:

var allmap []map[string]interface{} var structs []data _, item := range allmap {   var data data   var v interface{}   var ok bool   if v, ok := item["value"]; ok {     data.valid = v   } else {     data.valid = true   }   id v, ok := item["name"]; ok {     data.name = v   }   ...   structs = append(structs, data) } return structs 

right struct i'm working has 14 fields, of them have values want assign defaults, others fine leave blank, of them have iterated through using approach.

is there better way?

you can use json.rawmessage type defer unmarshaling json text value. if use type, json text stored in without unmarshaling (so can unmarshal fragment later on wish).

so in case if try unmarshal slice of such rawmessage, can use technique linked in question, can iterate on slice of raw values (which json text each data), create data struct values want defaults missing values, , unmarshal slice element prepared struct. that's all.

it looks this:

alljson := []json.rawmessage{} if err := json.unmarshal(src, &alljson); err != nil {     panic(err) }  alldata := make([]data, len(alljson)) i, v := range alljson {     // here create data default values     alldata[i] = data{valid: true}     if err := json.unmarshal(v, &alldata[i]); err != nil {         panic(err)     } } 

try on go playground.

notes / variants

for efficiency (to avoid copying structs), can make alldata slice of pointers in above example, this:

alldata := make([]*data, len(alljson)) i, v := range alljson {     // here create data default values     alldata[i] = &data{valid: true}     if err := json.unmarshal(v, alldata[i]); err != nil {         panic(err)     } } 

if want keep using non-pointers, efficiency can "prepare" wished default values in slice elements itself, this:

alldata := make([]data, len(alljson)) i, v := range alljson {     // here set default values in slice elements     // set defer 0 values:     alldata[i].valid = true     if err := json.unmarshal(v, &alldata[i]); err != nil {         panic(err)     } } 

Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -