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 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化