2016-08-23 4 views
0

Externe API gibt leeres Array, wenn keine Objekte:Decode sowohl Karte und Array json

{"items":[]} 

... oder mit Artikel Karte:

{"items":{"1": {...}, "2": {...}}} 

Wie kann ich entschlüsseln beide? Ich habe versucht, mit dieser Struktur:

var response struct { 
    Items map[string]Item 
    Array []Item `json:"items"` 
} 

Aber es funktioniert nicht.

UPDATE: Beste, wenn sowohl (array und Objekt) eine map[string]Item (leer und gefüllt) produzieren

+0

Bitte beachten Sie, was ich will ** ** dekodieren bestehende json und ich habe ** einen Schlüssel ** und ** zwei Typen ** des Wertes –

+0

@Amd Bitte lesen Sie die Frage, bitte Array ist immer leer, es sollte leer sein 'map [string] Item {}' Objekt ist immer gefüllt, so sollte es gefüllt sein 'map [string] Item {...} ' –

+0

@Amd sollte es" Array "oder" Objekt "in' one' Feld vom Typ 'map [string] Item decodieren. –

Antwort

1

Wenn Sie ein entordnen brauchen Variabler Typ ist der einfachste Weg, in eine map[string]interface{} zu entpacken und type-assert (oder in diesem Fall type-switch) den Ausweg zu finden .

func Unmarshal(data []byte) (map[string]Item, error) { 
    var d struct { 
     Items interface{} `json:"items"` 
    } 
    if err := json.Unmarshal(data, &d); err != nil { 
     return nil, err 
    } 
    switch dv := d.Items.(type) { 
    case []interface{}: 
     if len(dv) == 0 { 
      return nil, nil 
     } 
    case map[string]interface{}: 
     m := make(map[string]Item) 
     for k, v := range dv { 
      m[k] = Item(v) 
     } 
     return m, nil 
    } 
    // fallthrough return if different type, or non-empty array 
    // Could have put this in a default case, but this catches non-empty arrays too 
    return nil, fmt.Errorf("unexpected type in json") 
} 

Hier ist ein Beispiel dafür, es für beide Ihre bereitgestellten Beispiele funktioniert: https://play.golang.org/p/c0oZX2-xpN

0

Versuchen dieses Arbeitscode (A):

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Item int 

type response struct { 
    Items map[string]Item `json:"Items"` 
    Array []Item   `json:"Array"` 
} 

func main() { 
    var d response 
    err := json.Unmarshal([]byte(`{"Items":{"A":1,"B":2,"C":3},"Array":[]}`), &d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(d) 
} 

output:

{map[C:3 A:1 B:2] []} 

Versuchen Sie diesen Arbeitscode (B):

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Item int 

type response struct { 
    Items map[string]Item `json:"Items"` 
    //Array []Item   `json:"Array"` 
} 

func main() { 
    var d response 
    err := json.Unmarshal([]byte(`{"Items":{"A":1,"B":2,"C":3},"Array":[]}`), &d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(d) 
} 

Ausgang:

{map[C:3 A:1 B:2]} 

Sie können json.Marshal und json.Unmarshal, wie dieser Arbeitscode (C) verwenden:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Item int 

type response struct { 
    Items map[string]Item `json:"Items"` 
    Array []Item   `json:"Array"` 
} 

func main() { 
    var test = response{ 
     Items: map[string]Item{"A": 1, "B": 2, "C": 3}, 
     Array: []Item{}, 
    } 
    body, err := json.Marshal(test) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(string(body)) // {"Items":{"A":1,"B":2,"C":3},"Array":[]} 

    var d response 
    err = json.Unmarshal(body, &d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(d) 
} 

Ausgang:

{"Items":{"A":1,"B":2,"C":3},"Array":[]} 
{map[A:1 B:2 C:3] []} 

Sie können {"A":1,"B":2,"C":3}-map[A:1 B:2 C:3]
und "[1,2,3]" zu [1 2 3], wie dieser Arbeitscode (D) Abstellungs:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Item int 

type response1 map[string]Item 
type response2 []Item 

func main() { 
    var d response1 
    err := json.Unmarshal([]byte(`{"A":1,"B":2,"C":3}`), &d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(d) // map[A:1 B:2 C:3] 

    var d2 response2 
    err2 := json.Unmarshal([]byte(`[1,2,3]`), &d2) 
    if err2 != nil { 
     panic(err2) 
    } 
    fmt.Println(d2) // [1 2 3] 
} 

Ausgang:

map[A:1 B:2 C:3] 
[1 2 3] 
+0

Ich brauche decodieren' Elemente', die Array oder Objekt sein können –