2 回答

TA貢獻(xiàn)1900條經(jīng)驗(yàn) 獲得超5個(gè)贊
您可以為此使用 json.Unmarshal 并根據(jù)您的條件解析數(shù)據(jù)。我只是這樣做"data",你也可以這樣做"services_with_info"
b := []byte(`{
"source": "some random source",
"table": "hosts_table",
"data": [
["address", "id", "services_with_info"],
["0.0.0.1", 1111, [
["service_3", "is very cool", 1],
["service_4", "is very cool", 2]
]
],
["0.0.0.2", 2222, [
["service_3", "is very cool", 3],
["service_4", "is very cool", 4]
]
]
]}`)
var f interface{}
err := json.Unmarshal(b, &f)
if err != nil {
fmt.Println(err)
return
}
m := f.(map[string]interface{})
result := make(map[string]interface{})
results := make(map[string][]map[string]interface{})
for k, v := range m {
if k == "data" {
s := v.([]interface{})
header := make([]interface{}, 3)
for i, u := range s {
if i == 0 {
header = u.([]interface{})
} else {
row := u.([]interface{})
for j, k := range header {
result[k.(string)] = row[j]
}
results["data"] = append(results["data"], result)
}
}
}
}
fmt.Println(results)
這里"results"是"data"根據(jù)需要。

TA貢獻(xiàn)1943條經(jīng)驗(yàn) 獲得超7個(gè)贊
我不確定我是否明白你想要什么。
可能是這樣的事情?可能它需要一些工作,比如制作指向結(jié)構(gòu)的指針切片而不是結(jié)構(gòu)切片以防止分配和復(fù)制,錯(cuò)誤處理,更多自定義邏輯來(lái)轉(zhuǎn)換值,匿名/封裝轉(zhuǎn)換過(guò)程中使用的私有結(jié)構(gòu),添加 json 標(biāo)記那些結(jié)構(gòu)等
我為 IncomingPaylod 上的 Data 字段創(chuàng)建自定義 Unmarshaller:解析預(yù)期數(shù)據(jù),將其轉(zhuǎn)換為 []MyData 并使用它更新 Data 字段。
我為 expected_data 和 expected_services_with_info 創(chuàng)建了自定義解組器,因?yàn)槲覀兤谕鳛橹禂?shù)組(3 個(gè)值:字符串、整數(shù)和 [字符串?dāng)?shù)組、int(?)、int]),但我想將其轉(zhuǎn)換為漂亮的結(jié)構(gòu)。如果您不喜歡它,可以將其刪除,將預(yù)期數(shù)據(jù)解組到 []interface{} 并像 []interface{}{string, int, []interface{}{string, int, int} } 一樣使用它。容易出錯(cuò),所以我更喜歡結(jié)構(gòu),它更容易閱讀、維護(hù)和重構(gòu)(我認(rèn)為你的應(yīng)用程序中有更多字段)。
https://play.golang.org/p/xHTvyhecra
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type IncomingPayload struct {
Source string `json:"source"`
Table string `json:"table"`
Data MyDataSlice `json:"data"`
}
type MyDataSlice []MyData
type MyData struct {
Address string `json:"address"`
ID string `json:"id"`
Services_with_info []MyServiceWithInfo `json:"services_with_info"`
}
type MyServiceWithInfo struct {
ServiceName string `json:"service_name"`
ServiceMessage string `json:"service_message"`
ServiceID int `json:"service_id"`
}
type expected_data struct {
IP string
ID int
Info []expected_services_with_info
}
type expected_services_with_info struct {
Name string
Desc string
ID int
}
func (ed *expected_data) UnmarshalJSON(buf []byte) error {
tmp := []interface{}{&ed.IP, &ed.ID, &ed.Info}
// converts ["address", "id", "services_with_info"] into a struct
// will unmarshall "services_with_info" (ed.Info) with *expected_services_with_info.UnmarshalJSON
json.Unmarshal(buf, &tmp)
return nil
}
func (es *expected_services_with_info) UnmarshalJSON(buf []byte) error {
tmp := []interface{}{&es.Name, &es.Desc, &es.ID}
// converts ["service_3", "is very cool", 1] into a struct
json.Unmarshal(buf, &tmp)
return nil
}
func (md *MyDataSlice) UnmarshalJSON(p []byte) error {
var incoming_data_slice []expected_data
json.Unmarshal(p, &incoming_data_slice)
//fmt.Println("incoming", incoming_data_slice)
//transform incoming_data_slice to your needs using your data type
for i := range incoming_data_slice {
my_data := MyData{
Address: incoming_data_slice[i].IP, //copy
ID: strconv.Itoa(incoming_data_slice[i].ID), //some transformation
//nil slice is totally fine, but if you wish you can do
//Data: make(MyDataSlice, len(incoming_data_slice)),
}
//not sure what would be best: "i := range data" or "_, v := range data" (second one makes a copy? and causes allocation)
for j := range incoming_data_slice[i].Info {
tmp := MyServiceWithInfo{
ServiceName: incoming_data_slice[i].Info[j].Name,
ServiceMessage: incoming_data_slice[i].Info[j].Desc,
ServiceID: incoming_data_slice[i].Info[j].ID,
}
my_data.Services_with_info = append(my_data.Services_with_info, tmp)
}
//and populate
*md = append(*md, my_data)
}
return nil
}
func main() {
test_json := `{
"source": "some random source",
"table": "hosts_table",
"data": [
["address", "id", "services_with_info"],
["0.0.0.1", 1111, [
["service_3", "is very cool", 1],
["service_4", "is very cool", 2]
]
],
["0.0.0.2", 2222, [
["service_3", "is very cool", 3],
["service_4", "is very cool", 4]
]
]
]}`
var payload IncomingPayload
json.Unmarshal([]byte(test_json), &payload)
fmt.Println("payload", payload)
buf, _ := json.MarshalIndent(payload, "", "\t")
fmt.Println(string(buf))
}
- 2 回答
- 0 關(guān)注
- 250 瀏覽
添加回答
舉報(bào)