Convert Interface{} to Struct

Hi,

I am loading a json file (see specimen below) into a generic interface{} object and I want to convert it into a formal struct. My problem is that the ‘properties’ → ‘help’ → ‘properties’ arrays repeat until the child ‘help’ array is NULL, which we don’t know in advance.

{
    "list": {
        "lstexampleA": [
            { "properties": [
                    {
                        "with": "OPTION1",
                        "help": [
                            {
                                "properties": [
                                    {   
                                        "with": null, 
                                        "help": null,
                                        "element": "MP0001"
                                    }
                                ]
                            },
                            {
                                "properties": [
                                    { 
                                        "with": null, 
                                        "help": null,  
                                        "element": "MP0002"
                                    }
                                ]                                           
                            }
                        ]
                    },
                    { 
                        "with": "OPTION6",
                        "help": null,
                        "element": 10
                    } 
                ],
                "element": 100
            }
        ],
        "lstexampleB": [ .....

        ]
    }
}

So something like this perhaps…

var olists []oList

type oList struct {
	OWith     string
	OHelp     []oList
    OElement  interface{}
}

Is there a standard way to traverse the interface{} object, building up the struct as we go…

Thanks

Steffi

Hi @Steff, welcome to the forum.

json.Unmarshall can handle nested data of the same kind.
To have Unmarshal() build a nested struct in Go, use a pointer to describe the child struct:

var lists []List

type List struct {
	With     string
	Help     []oList
    Element  *List
}

I changed the example from the Unmarshal documentation to parse nested Animal data as a proof of concept:

var jsonBlob = []byte(`[
	{"Name": "Platypus", "Order": "Monotremata", "Animal": 
		{"Name": "Plotypas", "Order": "Manatremoto", "Animal":
			{"Name": "Plytapos", "Order": "Menetromata" }
		}
	},
	{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`)
	type Animal struct {
		Name   string
		Order  string
		Animal *Animal
	}
	var animals []Animal
	err := json.Unmarshal(jsonBlob, &animals)
	if err != nil {
		fmt.Println("error:", err)
	}
	spew.Dump(animals)

Complete, runnable code available in the Playground.

Output (agreed, spew.Dump() might be a bit too verbose here, simply look at the overall structure rather than the details):

([]main.Animal) (len=2 cap=4) {
 (main.Animal) {
  Name: (string) (len=8) "Platypus",
  Order: (string) (len=11) "Monotremata",
  Animal: (*main.Animal)(0xc0000a05a0)({
   Name: (string) (len=8) "Plotypas",
   Order: (string) (len=11) "Manatremoto",
   Animal: (*main.Animal)(0xc0000a05d0)({
    Name: (string) (len=8) "Plytapos",
    Order: (string) (len=11) "Menetromata",
    Animal: (*main.Animal)(<nil>)
   })
  })
 },
 (main.Animal) {
  Name: (string) (len=5) "Quoll",
  Order: (string) (len=14) "Dasyuromorphia",
  Animal: (*main.Animal)(<nil>)
 }
}
1 Like

@christophberger. Thank you very much. Works perfectly for me.

1 Like

Perfect! Glad to hear it’s working for your scenario.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.