arrays - 如何解析这个 JSON 数组?
问题描述
我有一个来自 Kraken websocket 的 JSON,如下所示:
myJsonString := []byte(`[320,{"as":[["27346.80000","0.48700000","1609084588.716887"],["27350.00000","1.38867881","1609084599.606134"]],"bs":[["27346.70000","0.39439437","1609084613.201520"],["27342.10000","0.08750000","1609084611.036191"]]},"book-10","XBT/USD"]`)
我想解组到这样的结构:
type OrderBook struct {
ChannelID int
A []OrderBookItem `json:"as"`
B []OrderBookItem `json:"bs"`
Depth string
Pair string
}
type OrderBookItem struct {
Price float64
Volume float64
Time float64
}
我尝试将 unmarshal 放入一个切片中,但它没有给出所需的结果,因为它只是返回一个带有零的结构。我读了这个答案How to parse JSON arrays with two different data types into a struct in Golang,但那里的消息似乎不是一个数组。
func main() {
myJsonString := []byte(`[320,{"as":[["27346.80000","0.48700000","1609084588.716887"],["27350.00000","1.38867881","1609084599.606134"]],"bs":[["27346.70000","0.39439437","1609084613.201520"],["27342.10000","0.08750000","1609084611.036191"]]},"book-10","XBT/USD"]`)
var raw []OrderBook
json.Unmarshal(myJsonString, &raw)
fmt.Println(raw)
}
结果:
[{0 [] [] } {0 [{0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0}] [{0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0} {0 0 0}] } {0 [] [] } {0 [] [] }]
我还尝试使用 interface{} 解组并使用 switch 来访问这些值,但这似乎很麻烦。
将其解组为结构的最佳做法是什么?
解决方案
您可以UnmarshalJSON
为您的类型实现自定义方法。
func (ob *OrderBook) UnmarshalJSON(b []byte) error {
var values []interface{}
err := json.Unmarshal(b, &values)
if err != nil {
return err
}
if len(values) != 4 {
return fmt.Errorf("unexpected number of order book values: %d", len(values))
}
ob.ChannelID = int(values[0].(float64))
ob.Depth = values[2].(string)
ob.Pair = values[3].(string)
m := values[1].(map[string]interface{})
ob.A, err = parseOrderBookItems(m["as"].([]interface{}))
if err != nil {
return err
}
ob.B, err = parseOrderBookItems(m["bs"].([]interface{}))
return err
}
func parseOrderBookItems(items []interface{}) ([]OrderBookItem, error) {
bookItems := make([]OrderBookItem, len(items))
for i, item := range items {
values := item.([]interface{})
if len(values) != 3 {
return nil, fmt.Errorf("unexpected number of order book item values: %d", len(values))
}
obi := OrderBookItem{}
f, err := strconv.ParseFloat(values[0].(string), 64)
if err != nil {
return nil, err
}
obi.Price = f
f, err = strconv.ParseFloat(values[1].(string), 64)
if err != nil {
return nil, err
}
obi.Volume = f
f, err = strconv.ParseFloat(values[2].(string), 64)
if err != nil {
return nil, err
}
obi.Time = f
bookItems[i] = obi
}
return bookItems, nil
}
这是操场上的一个例子:https: //play.golang.org/p/j7ydQCiqpcS。
推荐阅读
- cvxpy - python模块的递归自动重载
- node.js - JSDoc:适用于孙子类的文档泛型类型
- sql - 如何使用 SQL DISTINCT 从多个列中删除重复项?
- php - php7 从数组中获取特定值
- azure-active-directory - B2B 访客邀请失败并出现 503 错误
- bar-chart - 在 spotfire 中使用按钮限制数据
- ios - 如何显示搜索结果,如 iOS“联系人”应用
- sql - SQL查询返回财政年度和季度
- api - 如何阻止 Google 撤销我的刷新令牌?
- php - 在 Woocommerce 3 中获取 PayTrace 支付网关的订单自定义元数据