2017-08-02 5 views
0

Comment puis-je convertir un objet JSON complexe en une carte avec tous les bons types dans Golang. Est-ce que je dois absolument faire la chose typique de Golang où je crée une structure avec les champs que je sais être présents ou y a-t-il une manière généralisée d'obtenir les champs dans tous les bons types?Convertir un JSON complexe en carte dans Golang

Voici un exemple d'un JSON que je veux transformer en une carte:

{ 
    "people": [ 
     { 
      "diffs": [ 
       77 
      ], 
      "original": { 
       "name": "Nick", 
       "active": "Active", 
       "email": "[email protected]" 
      }, 
      "id": "21" 
     } 
    ] 
} 
+0

Bienvenue dans une langue typée statiquement. Avec le paquet 'json', vous pouvez toujours Unmarshal dans une interface' map [string] {} 'mais ce n'est généralement pas ce que vous voulez vraiment. – RayfenWindspear

Répondre

1

Vous pouvez construire une fonction récursive avec un commutateur d'assertion de type à l'affirmation du tableau JSON dans une carte multi-dimensionnelle ou une carte aplatie. Malheureusement, votre carte multidimensionnelle va se compliquer très rapidement. Ce que je veux dire, c'est que vous avez souvent besoin de mapper au moins quelques dimensions (par exemple: map [chaîne] carte [chaîne] carte [chaîne] chaîne), quand vous avez un tableau JSON imbriqué tel que " les gens "ci-dessus.

Si vous essayez d'aplatir une baie JSON imbriquée, vos clés finiront par se chevaucher (c'est-à-dire que vous ne pouvez utiliser la clé "name" qu'une seule fois). Vous pourriez étiqueter les clés - quelque chose comme "nom_1": "Nick", mais cette solution peut ne pas fonctionner pour votre cas d'utilisation.

Si vous voulez aller la route multi-dimensionnelle, ce paquet peut bien fonctionner pour vos besoins: http://github.com/Jeffail/gabs

Je vais vous donner un exemple sur mesure, puis deux exemples du lien vers la page GitHub de Gabs :

package main 

import (
    "fmt" 
    "github.com/Jeffail/gabs" 
) 

func main() { 

    jsonS := `{ 
     "people": [ 
      { 
       "diffs": [ 
        77 
       ], 
       "original": { 
        "name": "Nick", 
        "active": "Active", 
        "email": "[email protected]" 
       }, 
       "id": "21" 
      } 
     ] 
    }` 

    gabsCon, err := gabs.ParseJSON([]byte(jsonS)) 

    if err != nil { 
     fmt.Println("gabs ParseJSON failed") 
    } 

    n1, ok := gabsCon.Path("people.original.name").Data().(string) 

    if !ok { 
     fmt.Println("gabs path failed") 
    } 

    fmt.Println(n1) 
} 

Voici un exemple non adapté, qui imprimerait - premier, deuxième, troisième):

jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":[ "first", "second", "third" ]}`)) 

// S is shorthand for Search 
children, _ := jsonParsed.S("array").Children() 
for _, child := range children { 
    fmt.Println(child.Data().(string)) 
} 

Et, un autre exemple, qui imprimerait - 1, 2, 3:

jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":[ {"value":1}, {"value":2}, {"value":3} ]}`)) 

fmt.Println(jsonParsed.Path("array.value").String())