2014-10-10 106 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