如何将包含数组的 JSON 对象转换为单个 Struct 实例
How can I convert JSON object which contains an array into a single Struct instance
我发现有很多类似的问题,但我仍然找不到问题的答案。
我的 JSON 文件的相关部分如下所示:
{
...,
"roi": {
"roi": [
{
"id": "original",
"x": 600,
"y": 410,
"width": 540.0,
"height": 240.0
}
]
},
...
}
这是我定义结构的方式:
type RoI struct {
Id string `json:"string"` // Default Value: "original"
Width float64 `json:"width" validate:"gte=0,lte=10000"` // RoI width (from 0 - 10000) - how much we move to the right from (X,Y) point
Height float64 `json:"height" validate:"gte=0,lte=10000"` // RoI height (from 0 - 10000) - how much we move down from the (X,Y) point
X float64 `json:"x" validate:"gte=0,lte=10000"` // X coordinate which together with Y coordinate forms a top left corner of the RoI (from 0 - 10000)
Y float64 `json:"y" validate:"gte=0,lte=10000"` // Y coordinate which together with X coordinate forms a top left corner of the RoI (from 0 - 10000)
}
我假设我总是会在 "roi"
数组中得到 1 个元素。请注意,出于许多不同的目的,我需要保留此结构。
我想将 roi
数组中的第 1 个元素解析为 RoI
结构。到目前为止,这是我尝试过的方法:
var detectionResMap = make(map[string]interface{})
err = json.Unmarshal(fileByteArr, &detectionResMap)
if err != nil {
glog.Errorf("Error occurred while trying to Unmarshal JSON data into detectionResMap. Error message - %v", err)
return err
}
当我打印出 detectionResMap["roi"]
时使用:
glog.Infof("[INFO]: %v", reflect.TypeOf(detectionResMap["roi"]))
glog.Infof("[INFO]: %v", detectionResMap["roi"])
我得到以下输出:
I0801 19:56:45.392362 125787 v2.go:87] [INFO]: map[string]interface {}
I0801 19:56:45.392484 125787 v2.go:88] [INFO]: map[roi:[map[height:240 id:original width:540 x:600 y:410]]]
但是,一旦我尝试使用
将 detectionResMap["roi"]
解组为 RoI
roiByteArr, err := json.Marshal(detectionResMap["roi"])
if err != nil {
glog.Errorf("Error occurred while trying to Marshal detectionResMap[\"roi\"] into byte array. Error message - %v", err)
return err
}
roi := config.RoI{}
if err := json.Unmarshal(roiByteArr, &roi); err != nil {
glog.Errorf("Error occurred while trying to unmarshal roi data. Error message - %v", err)
return err
}
我得到以下信息:
{ 0 0 0 0}
如果我尝试将其更改为 []RoI
,我会得到:
json: cannot unmarshal object into Go value of type []config.RoI
任何帮助将不胜感激
您的尝试无效,因为 roiByteArr
是 {"roi": [{ ... }]}
,这不匹配 config.RoI
也不匹配 []config.RoI
。
您可以声明一个匹配 json 的类型:
type roiobj struct {
RoI struct {
RoI []RoI `json:"roi"`
} `json:"roi"`
}
var obj roiobj
if err := json.Unmarshal(fileByteArr, &obj); err != nil {
panic(err)
}
roi := obj.RoI.RoI[0]
或正确检索与您的结构匹配的对象:
// in your real code do not omit safe type assertion like i'm doing here.
obj := detectionResMap["roi"].(map[string]interface{})["roi"].([]interface{})[0]
roiByteArr, err := json.Marshal(obj)
if err != nil {
return err
}
roi := config.RoI{}
if err := json.Unmarshal(roiByteArr, &roi); err != nil {
return err
}
或实现自定义解组器:
func (r *RoI) UnmarshalJSON(b []byte) error {
type roi RoI
var obj struct {
RoI []roi
}
if err := json.Unmarshal(b, &obj); err != nil {
return err
}
*r = RoI(obj.RoI[0])
return nil
}
var fileobj struct {
// ...
RoI RoI `json:"roi"`
// ...
}
if err := json.Unmarshal(fileByteArr, &fileobj); err != nil {
panic(err)
}
roi := fileobj.RoI
我发现有很多类似的问题,但我仍然找不到问题的答案。
我的 JSON 文件的相关部分如下所示:
{
...,
"roi": {
"roi": [
{
"id": "original",
"x": 600,
"y": 410,
"width": 540.0,
"height": 240.0
}
]
},
...
}
这是我定义结构的方式:
type RoI struct {
Id string `json:"string"` // Default Value: "original"
Width float64 `json:"width" validate:"gte=0,lte=10000"` // RoI width (from 0 - 10000) - how much we move to the right from (X,Y) point
Height float64 `json:"height" validate:"gte=0,lte=10000"` // RoI height (from 0 - 10000) - how much we move down from the (X,Y) point
X float64 `json:"x" validate:"gte=0,lte=10000"` // X coordinate which together with Y coordinate forms a top left corner of the RoI (from 0 - 10000)
Y float64 `json:"y" validate:"gte=0,lte=10000"` // Y coordinate which together with X coordinate forms a top left corner of the RoI (from 0 - 10000)
}
我假设我总是会在 "roi"
数组中得到 1 个元素。请注意,出于许多不同的目的,我需要保留此结构。
我想将 roi
数组中的第 1 个元素解析为 RoI
结构。到目前为止,这是我尝试过的方法:
var detectionResMap = make(map[string]interface{})
err = json.Unmarshal(fileByteArr, &detectionResMap)
if err != nil {
glog.Errorf("Error occurred while trying to Unmarshal JSON data into detectionResMap. Error message - %v", err)
return err
}
当我打印出 detectionResMap["roi"]
时使用:
glog.Infof("[INFO]: %v", reflect.TypeOf(detectionResMap["roi"]))
glog.Infof("[INFO]: %v", detectionResMap["roi"])
我得到以下输出:
I0801 19:56:45.392362 125787 v2.go:87] [INFO]: map[string]interface {}
I0801 19:56:45.392484 125787 v2.go:88] [INFO]: map[roi:[map[height:240 id:original width:540 x:600 y:410]]]
但是,一旦我尝试使用
将detectionResMap["roi"]
解组为 RoI
roiByteArr, err := json.Marshal(detectionResMap["roi"])
if err != nil {
glog.Errorf("Error occurred while trying to Marshal detectionResMap[\"roi\"] into byte array. Error message - %v", err)
return err
}
roi := config.RoI{}
if err := json.Unmarshal(roiByteArr, &roi); err != nil {
glog.Errorf("Error occurred while trying to unmarshal roi data. Error message - %v", err)
return err
}
我得到以下信息:
{ 0 0 0 0}
如果我尝试将其更改为 []RoI
,我会得到:
json: cannot unmarshal object into Go value of type []config.RoI
任何帮助将不胜感激
您的尝试无效,因为 roiByteArr
是 {"roi": [{ ... }]}
,这不匹配 config.RoI
也不匹配 []config.RoI
。
您可以声明一个匹配 json 的类型:
type roiobj struct {
RoI struct {
RoI []RoI `json:"roi"`
} `json:"roi"`
}
var obj roiobj
if err := json.Unmarshal(fileByteArr, &obj); err != nil {
panic(err)
}
roi := obj.RoI.RoI[0]
或正确检索与您的结构匹配的对象:
// in your real code do not omit safe type assertion like i'm doing here.
obj := detectionResMap["roi"].(map[string]interface{})["roi"].([]interface{})[0]
roiByteArr, err := json.Marshal(obj)
if err != nil {
return err
}
roi := config.RoI{}
if err := json.Unmarshal(roiByteArr, &roi); err != nil {
return err
}
或实现自定义解组器:
func (r *RoI) UnmarshalJSON(b []byte) error {
type roi RoI
var obj struct {
RoI []roi
}
if err := json.Unmarshal(b, &obj); err != nil {
return err
}
*r = RoI(obj.RoI[0])
return nil
}
var fileobj struct {
// ...
RoI RoI `json:"roi"`
// ...
}
if err := json.Unmarshal(fileByteArr, &fileobj); err != nil {
panic(err)
}
roi := fileobj.RoI