douqianbiao4216 2014-10-10 02:44
浏览 137
已采纳

检索嵌套Json数组的第一条记录

I'm trying to parse the first record in an embedded JSON array and create an object based on a subset of those properties. I have this working, but based on this question, I have to think there is a more elegant/less brittle way of doing this. For a bit more background, this is a result set from a call to the musicbrainz JSON web service, and I am treating the first artists record as the artist I am looking for.

The format of the JSON is like this:

{
    "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": []
    },
    ...
}

Here's the code I have so far. I'd like to be able to use my ArtistCollection type to get around some of the interface{} stuff, but I'm stuck as to how. I also don't want to bother with mapping all of the properties of the artist record, I'm only interested in the "name" and "id" values.

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)
    }
}

Requisite go playground link

  • 写回答

1条回答 默认 最新

  • dstt1818 2014-10-10 02:50
    关注

    Define a type that matches the structure of the JSON and unmarshal to a value of that type. I use an anonymous type below. Use an array of length one to grab the first artist record:

    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
    ", result.Artists[0])
    }
    

    <kbd>playground</kbd>

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 树莓派5怎么用camera module 3啊
  • ¥20 java在应用程序里获取不到扬声器设备
  • ¥15 echarts动画效果的问题,请帮我添加一个动画。不要机器人回答。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加