2017-04-01 5 views
1

私は外出先で動作するサードパーティjson APIを持っています。
データをキー値として返すエンドポイントがいくつかあります。例えば
は、ここではステータスのためにJSONです:だからカスタムJsonマーシャリング

{ 
    "result": { 
    "0": "done", 
    "1": "incomplete", 
    "2": "completed", 
    .... 
    } 
} 

あなたはオブジェクトである配列ではありません見るように。
は、それが値を抽出するために

type StatusReposne struct { 
    Result map[string]string `json:"result"` 
} 

とコードのような追加の構造体を使用せずに

type Status struct { 
    Id int 
    Status string 
} 

のようにオブジェクトの配列にJSONのこの種をマーシャリングすることは可能ですか?

+0

:このコードは、へ/ Status秒のスライスから元帥/非整列化データへの手段を提供しません。それをマップに最初に非整列化し、そのマップをループして 'Status'構造体のスライスを構築するか、' type Result [] Status'のような型を作成し、その型のための非マーシャラインタフェースを実装します。 – mkopriva

答えて

2

@mkoprivaはコメントに記載されているように、余分な作業はできません。私の知る限りそれはプレーン `エンコーディング/ json.Unmarshal`で、あなたは、いくつかの余分な仕事をしなくてはできません知っているよう

func main() { 
    sr := new(StatusReposne) 

    json.Unmarshal([]byte(input), sr) 
    fmt.Printf("%+v\n", sr) 

    js, _ := json.Marshal(sr) 
    fmt.Printf("%s\n", js) 
} 

type StatusReposne struct { 
    Result []Status `json:"result"` 
} 

type Status struct { 
    Id  int 
    Status string 
} 

func (x *StatusReposne) MarshalJSON() ([]byte, error) { 
    var buffer struct { 
     Result map[string]string `json:"result"` 
    } 
    buffer.Result = make(map[string]string) 
    for _, v := range x.Result { 
     buffer.Result[strconv.Itoa(v.Id)] = v.Status 
    } 
    return json.Marshal(&buffer) 
} 

func (x *StatusReposne) UnmarshalJSON(b []byte) error { 
    var buffer struct { 
     Result map[string]string `json:"result"` 
    } 
    buffer.Result = make(map[string]string) 
    json.Unmarshal(b, &buffer) 
    for k, v := range buffer.Result { 
     k, _ := strconv.Atoi(k) 
     x.Result = append(x.Result, Status{Id: k, Status: v}) 
    } 
    return nil 
} 

var input = `{ 
    "result": { 
    "0": "done", 
    "1": "incomplete", 
    "2": "completed" 
    } 
}` 
関連する問題