2014-10-10 34 views
0

我想解析嵌入式JSON數組中的第一條記錄並基於這些屬性的子集創建一個對象。我有這個工作,但基於這個question,我不得不認爲有一個更優雅/更脆弱的方式來做到這一點。對於更多背景,這是從調用JSON Web服務的結果集,我將第一個artists記錄視爲我正在尋找的藝術家。檢索嵌套的JSON數組的第一個記錄

的JSON格式是這樣的:

{ 
    "created": "2014-10-08T23:55:54.343Z", 
    "count": 458, 
    "offset": 0, 
    "artists": [{ 
     "id": "83b9cbe7-9857-49e2-ab8e-b57b01038103", 
     "type": "Group", 
     "score": "100", 
     "name": "Pearl Jam", 
     "sort-name": "Pearl Jam", 
     "country": "US", 
     "area": { 
      "id": "489ce91b-6658-3307-9877-795b68554c98", 
      "name": "United States", 
      "sort-name": "United States" 
     }, 
     "begin-area": { 
      "id": "10adc6b5-63bf-4b4e-993e-ed83b05c22fc", 
      "name": "Seattle", 
      "sort-name": "Seattle" 
     }, 
     "life-span": { 
      "begin": "1990", 
      "ended": null 
     }, 
     "aliases": [], 
     "tags": [] 
    }, 
    ... 
} 

這裏是我到目前爲止的代碼。我想能夠使用我的ArtistCollection類型來解決一些interface{}的東西,但我堅持如何。我也不想打擾映射藝術家記錄的所有屬性,我只對"name""id"值感興趣。

package main 

import (
    "fmt" 
    "encoding/json" 
    ) 

type Artist struct { 
    Id string 
    Name string 
} 

type ArtistCollection struct { 
    Artists []Artist 
} 

func main() { 
    raw := //json formatted byte array 
    var topLevel interface{} 
    err := json.Unmarshal(raw, &topLevel) 
    if err != nil { 
     fmt.Println("Uh oh") 
    } else { 
     m := topLevel.(map[string]interface{}) 
     //this seems really hacky/brittle, there has to be a better way? 
     result := (m["artists"].([]interface{})[0]).(map[string]interface{}) 
     artist := new(Artist) 
     artist.Id = result["id"].(string) 
     artist.Name = result["name"].(string) 
     fmt.Println(artist) 
    } 
} 

必要去遊樂場link

回答

2

定義該JSON的結構和解組匹配於該類型的值的類型。我在下面使用匿名類型。使用一個長度的數組搶到第一位藝術家紀錄:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Artist struct { 
    Id string 
    Name string 
} 

func main() { 
    raw := // JSON formatted byte array 
    var result struct { 
     Artists artist 
    } 
    err := json.Unmarshal(raw, &result) 
    if err != nil { 
     fmt.Println(err) 
     return 
    } 
    fmt.Printf("%#v\n", result.Artists[0]) 
} 

playground

+0

這是有道理的,謝謝!出於某種原因,我並不期待它有可能編組成僅僅部分代表JSON的類型。 – 2014-10-10 03:12:48

+0

注意最後編輯(在此評論的時間)不正確;它與操場鏈接上的代碼不匹配,並且不會編譯。它應該是另一個答案中的藝術家[]藝術家。 – 2015-03-22 17:14:40