recorrer golang functions for array arrays go struct

arrays - golang - Unmarshal 2 estructuras diferentes en una rebanada



golang struct in struct (3)

Creo que la respuesta de Peter es asombrosa.

Opción 1:

type ParallelData [ urlData UrlData formData FormData ]

si necesita la estructura anterior, puede definirla como

type UrlData struct { Url string `json:"Url,omitempty"` Name string `json:"Name,omitempty"` } type FormData struct { FormName string `json:"FormName,omitempty"` FormNumber string `json:"FormNumber,omitempty"` FormSlug string `json:"FormSlug,omitempty"` } type ParallelData struct { UrlData UrlData `json:"UrlData,omitempty"` FormData FormData `json:"FormData,omitempty"` }

En este caso, su json se verá como

[ { "UrlData":{ "Url":"test.url", "Name":"testname" } }, { "FormData":{ "FormName":"Test - 2018", "FormNumber":"43", "FormSlug":"test-2018" } } ]

Opcion 2:

Has proporcionado los siguientes json:

[ { "Url":"test.url", "Name":"testname" }, { "FormName":"Test - 2018", "FormNumber":43, "FormSlug":"test-2018" } ]

Si su json realmente se parece, entonces puede usar la siguiente struct

type UrlData struct { Url string `json:Url` Name string `json:Name` } type FormData struct { FormName string `json:FormName` FormNumber int `json:FormNumber` FormSlug string `json:FormSlug` } type ParallelData struct { UrlData FormData }

Para ambas opciones, puede desmarcar su json de esta manera

var parallelData []ParallelData err := json.Unmarshal([]byte(str), &parallelData) if err != nil { panic(err) } fmt.Println(parallelData)

Ver opción 1 en el playground de playground

Ver opción 2 en el playground de playground

Mi información json de entrada es esta (no se puede cambiar, desde un recurso externo):

[{ "Url": "test.url", "Name": "testname" },{ "FormName": "Test - 2018", "FormNumber": 43, "FormSlug": "test-2018" }]

Tengo dos estructuras que siempre coincidirán con los datos dentro de la matriz:

type UrlData struct{ "Url" string `json:Url` "Name" string `json:Name` } type FormData struct{ "FormName" string `json:FormName` "FormNumber" string `json:FormNumber` "FormSlug" string `json:FormSlug` }

Obviamente, el siguiente código no funcionará, pero es posible en el nivel superior (o de otro modo) declarar algo como esto:

type ParallelData [ urlData UrlData formData FormData ]


Puede desarmar en una map[string]interface{} por ejemplo:

type ParallelData map[string]interface{} func main() { textBytes := []byte(`[ { "Url": "test.url", "Name": "testname" }, { "FormName": "Test - 2018", "FormNumber": 43, "FormSlug": "test-2018" }]`) var acc []ParallelData json.Unmarshal(textBytes, &acc) fmt.Printf("%+v", acc) }

Salida:

=> [map[Url:test.url Name:testname] map[FormName:Test - 2018 FormNumber:43 FormSlug:test-2018]]

Playground


Use un proceso de dos pasos para desarmar. Primero, desarme una lista de JSON arbitrarios, luego desarme el primer y segundo elemento de esa lista en sus respectivos tipos.

Puede implementar esa lógica en un método llamado UnmarshalJSON, implementando así la interfaz json.Unmarshaler . Esto le dará el tipo de compuesto que está buscando:

type ParallelData struct { UrlData UrlData FormData FormData } // UnmarshalJSON implements json.Unmarshaler. func (p *ParallelData) UnmarshalJSON(b []byte) error { var records []json.RawMessage if err := json.Unmarshal(b, &records); err != nil { return err } if len(records) < 2 { return errors.New("Short JSON array") } if err := json.Unmarshal(records[0], &p.UrlData); err != nil { return err } if err := json.Unmarshal(records[1], &p.FormData); err != nil { return err } return nil }

Pruébalo en el patio de recreo: https://play.golang.org/p/QMn_rbJj-P-