doubi3996 2017-02-21 21:06
浏览 56
已采纳

在Go中解组数组的JSON数组

I want to parse some json data in go. The data looks like this:

{"id":"someId","key_1":"value_1","key_2":"value_2","key_3":"value_3","points":[[1487100466412,"50.032178","8.526018",300,0.0,26,0],[1487100471563,"50.030869","8.525949",300,0.0,38,0],[1487100475722,"50.028514","8.525959",225,0.0,69,-900],[1487100480834,"50.025827","8.525793",275,0.0,92,-262],...]}

I built a go struct:

type SomeStruct struct {
   ID   string `json:"id"`
   Key1 string `json:"key_1"`
   Key2 string `json:"key_2"`
   Key3 string `json:"key_3"`
   Points []Point `json:"points"`
}

type Point struct {
   Timestamp int64 `json:"0"`
   Latitude float64 `json:"1,string"`
   Longitude float64 `json:"2,string"`
   Altitude int `json:"3"` 
   Value1 float64 `json:"4"`
   Value2 int `json:"5"`
   Value3 int `json:"6"`      
}

I unmarshal the json data

var track SomeStruct
error := json.Unmarshal(data,&track)
if(error != nil){
    fmt.Printf("Error while parsing data: %s", error)
}

json: cannot unmarshal array into Go value of type Point{someId value_1 value_2 value_3 [{0 0 0 0 0 0 0} {0 0 0 0 0 0 0} {0 0 0 0 0 0 0}...]}

So the first json keys are parsed correctly, but I cannot figure out how to get the point data, which is an array of arrays.

The generate struct is also the suggest one from here, except I don't use a nested struct but a separate type. Using the suggested nested struct does not make a difference: JSON-to-Go

Do I need to implement my own Unmarshaller for this?

======= UPDATE SOLUTION ============

It is enough to implement the UnmarshalJSON interface for the Point struct. The example below does not contain proper error handling but it show the direction.

Playground example

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type SomeStruct struct {
    ID     string  `json:"id"`
    Key1   string  `json:"key_1"`
    Key2   string  `json:"key_2"`
    Key3   string  `json:"key_3"`
    Points []Point `json:"points"`
}

type Point struct {
    Timestamp int64
    Latitude  float64
    Longitude float64
    Altitude  int
    Value1    float64
    Value2    int16
    Value3    int16
}

func (tp *Point) UnmarshalJSON(data []byte) error {
    var v []interface{}
    if err := json.Unmarshal(data, &v); err != nil {
        fmt.Printf("Error whilde decoding %v
", err)
        return err
    }
    tp.Timestamp = int64(v[0].(float64))
    tp.Latitude, _ = strconv.ParseFloat(v[1].(string), 64)
    tp.Longitude, _ = strconv.ParseFloat(v[2].(string), 64)
    tp.Altitude = int(v[3].(float64))
    tp.Value1 = v[4].(float64)
    tp.Value2 = int16(v[5].(float64))
    tp.Value3 = int16(v[6].(float64))

    return nil
}

func main() {

    const data =    `{"id":"someId","key_1":"value_1","key_2":"value_2","key_3":"value_3","points":[[1487100466412,"50.032178","8.526018",300,0.0,26,0],[1487100471563,"50.030869","8.525949",300,0.0,38,0],[1487100475722,"50.028514","8.525959",225,0.0,69,-900],[1487100480834,"50.025827","8.525793",275,0.0,92,-262]]}`

var something SomeStruct
json.Unmarshal([]byte(data), &something)

fmt.Printf("%v", something)
}
  • 写回答

1条回答 默认 最新

  • doujiang1832 2017-02-21 22:06
    关注

    Do I need to implement my own Unmarshaller for this?

    Yes.

    You're trying to unmarshal an array into a struct (Point), which means you need to tell the JSON unmarshaler how the array values map to the struct values.

    Also note that your tags are incorrect in your Point definition. json tags refer to the key names, but arrays don't have keys (in JavaScript they can be accessed as if they do, but this isn't JavaScript). In other words, json:"0" will only work if your JSON looks like {"0":123}. If you implement your own unmarshaler, you can just get rid of those json tags.

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

报告相同问题?

悬赏问题

  • ¥30 matlab ode45 未发现警告,但是运行出错
  • ¥15 vscode platformio
  • ¥15 代写uni代码,app唤醒
  • ¥15 全志t113i启动qt应用程序提示internal error
  • ¥15 ensp可以看看嘛.
  • ¥80 51单片机C语言代码解决单片机为AT89C52是清翔单片机
  • ¥60 优博讯DT50高通安卓11系统刷完机自动进去fastboot模式
  • ¥15 minist数字识别
  • ¥15 在安装gym库的pygame时遇到问题,不知道如何解决
  • ¥20 uniapp中的webview 使用的是本地的vue页面,在模拟器上显示无法打开