Arrays 将json单元素数组转换为字符串
在Go中,我必须解析这个json:Arrays 将json单元素数组转换为字符串,arrays,json,go,decode,Arrays,Json,Go,Decode,在Go中,我必须解析这个json: { "response": [ { "message": [ "hello world" ], "misc": [ { "timestamp": [ "2017-06-28T05:52:39.347Z" ], "server": [ "server-0101"
{
"response": [
{
"message": [
"hello world"
],
"misc": [
{
"timestamp": [
"2017-06-28T05:52:39.347Z"
],
"server": [
"server-0101"
]
}
]
}
]
}
{
"response": {
"message": "hello world",
"misc": {
"timestamp": "2017-06-28T05:52:39.347Z",
"server": "server-0101"
}
}
}
我想在Go中获得一个对象,它不包含所有不必要的数组,只包含一个字符串。源json在每个数组中永远不会有超过一个字符串
所以我想要得到的最终结果是这个json:
{
"response": [
{
"message": [
"hello world"
],
"misc": [
{
"timestamp": [
"2017-06-28T05:52:39.347Z"
],
"server": [
"server-0101"
]
}
]
}
]
}
{
"response": {
"message": "hello world",
"misc": {
"timestamp": "2017-06-28T05:52:39.347Z",
"server": "server-0101"
}
}
}
或Go中的等效对象
现在我必须使用Response[0].Misc[0].Timestamp[0]
来访问看起来很奇怪的数据
我想在Go中获得一个对象,它不包含所有不必要的数组,只包含一个字符串
困难的方法是:手工解析JSON(编写我们自己的解析器)
明智的方法是:通过包编码/json将其解组为与json匹配的某种Go类型,或者解组为某种通用的
接口{}
,然后将片段复制为不同的、更简单的Go类型。您可以覆盖结构的json.Marshal
/json.Unmarshal
方法的默认行为,通过正确定义自己的MarshalJSON
或UnmarshalJSON
下面是需要解码的结构的简化版本的代码摘录
type Response struct {
Message string `json:"message"`
}
// UnmarshalJSON overrides the default behaviour for JSON unmarshal method.
func (r *Response) UnmarshalJSON(data []byte) error {
auxResponse := &struct {
Message []string `json:"message"`
}{}
if err := json.Unmarshal(data, &auxResponse); err != nil {
return err
}
// Consider to add some checks on array length :)
r.Message = auxResponse.Message[0]
return nil
}
您可以访问完整的工作示例
我建议您阅读这篇有趣的文章。创建您自己的解组器可能是最好的,但这是一种模拟您想要实现的目标的快速方法
package main
import (
"encoding/json"
"fmt"
)
// JSON ...
var JSON = `{
"response": [
{
"message": [
"hello world"
],
"misc": [
{
"timestamp": [
"2017-06-28T05:52:39.347Z"
],
"server": [
"server-0101"
]
}
]
}
]
}
`
type rawObject struct {
Response []struct {
Message []string `json:"message"`
Misc []interface{} `json:"misc"`
} `json:"response"`
}
type clean struct {
Message string `json:"message"`
Misc map[string]interface{} `json:"misc"`
}
func main() {
var o rawObject
var c clean
// init map
c.Misc = make(map[string]interface{})
// unmarshall the raw data
json.Unmarshal([]byte(JSON), &o)
for _, res := range o.Response { // I assume there should only be one response, don't know why this is wrapped as an array
// assume message is not really an array
c.Message = res.Message[0]
// convert []interface to map[string]interface
for _, m := range res.Misc {
for k, v := range m.(map[string]interface{}) {
c.Misc[k] = v
}
}
}
fmt.Printf("%+v\n", c)
}
我不喜欢这个答案的原因是它不太可重用。因此,可能应该创建一个函数并进行更多的错误检查(创建自定义解组器的一部分)。如果在大批量生产中使用,它可能会遇到一些内存问题,因为我必须创建一个原始对象来创建clean
对象。。但作为一个一次性脚本,它完成了任务。我认为我的clean结构没有将响应作为类型添加,因为我发现它是冗余的