英文:
Custom Json Marshaling
问题
我在Go语言中使用第三方的JSON API。它有一些返回键值对数据的端点。例如,这是一个关于状态的JSON示例:
{
"result": {
"0": "done",
"1": "incomplete",
"2": "completed",
....
}
}
你可以看到,它不是一个数组,而是一个对象。你想知道是否可以将这种类型的JSON解组为对象数组,类似于:
type Status struct {
Id int
Status string
}
而不使用额外的结构体,例如:
type StatusResponse struct {
Result map[string]string json:"result"
}
以及提取值的代码吗?
英文:
I have a third-party json api to work with in go.
It has some endpoints which return data as key-value.
For example here is json for statuses:
{
"result": {
"0": "done",
"1": "incomplete",
"2": "completed",
....
}
}
So as you see it is not an array it is an object.
Is it possible to marshal this kind of json to array of objects like
type Status struct {
Id int
Status string
}
without using additional struct like
type StatusReposne struct {
Result map[string]string `json:"result"`
}
and code to extract values?
答案1
得分: 2
根据@mkopriva在评论中的说法,如果不进行一些额外的工作是不可能的。这段代码提供了将数据编组/解组到一个Status
切片的方法:
func main() {
sr := new(StatusReposne)
json.Unmarshal([]byte(input), sr)
fmt.Printf("%+v\n", sr)
js, _ := json.Marshal(sr)
fmt.Printf("%s\n", js)
}
type StatusReposne struct {
Result []Status `json:"result"`
}
type Status struct {
Id int
Status string
}
func (x *StatusReposne) MarshalJSON() ([]byte, error) {
var buffer struct {
Result map[string]string `json:"result"`
}
buffer.Result = make(map[string]string)
for _, v := range x.Result {
buffer.Result[strconv.Itoa(v.Id)] = v.Status
}
return json.Marshal(&buffer)
}
func (x *StatusReposne) UnmarshalJSON(b []byte) error {
var buffer struct {
Result map[string]string `json:"result"`
}
buffer.Result = make(map[string]string)
json.Unmarshal(b, &buffer)
for k, v := range buffer.Result {
k, _ := strconv.Atoi(k)
x.Result = append(x.Result, Status{Id: k, Status: v})
}
return nil
}
var input = `{
"result": {
"0": "done",
"1": "incomplete",
"2": "completed"
}
}`
以上是要翻译的内容。
英文:
As @mkopriva stated in the comment, it's not possible without some extra work. This code does provide means to Marshal/Unmarshal data to/from a slice of Status
s:
func main() {
sr := new(StatusReposne)
json.Unmarshal([]byte(input), sr)
fmt.Printf("%+v\n", sr)
js, _ := json.Marshal(sr)
fmt.Printf("%s\n", js)
}
type StatusReposne struct {
Result []Status `json:"result"`
}
type Status struct {
Id int
Status string
}
func (x *StatusReposne) MarshalJSON() ([]byte, error) {
var buffer struct {
Result map[string]string `json:"result"`
}
buffer.Result = make(map[string]string)
for _, v := range x.Result {
buffer.Result[strconv.Itoa(v.Id)] = v.Status
}
return json.Marshal(&buffer)
}
func (x *StatusReposne) UnmarshalJSON(b []byte) error {
var buffer struct {
Result map[string]string `json:"result"`
}
buffer.Result = make(map[string]string)
json.Unmarshal(b, &buffer)
for k, v := range buffer.Result {
k, _ := strconv.Atoi(k)
x.Result = append(x.Result, Status{Id: k, Status: v})
}
return nil
}
var input = `{
"result": {
"0": "done",
"1": "incomplete",
"2": "completed"
}
}`
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论