Unmarshalling json into a Golang struct with a map of structs which contains a map of structs

huangapple go评论81阅读模式
英文:

Unmarshalling json into a Golang struct with a map of structs which contains a map of structs

问题

我相信可以使用多个结构体(一些临时结构体没有地图)来完成这个任务,但我不确定是否有更好的方法。

基本上,假设我有以下结构体:

type Event struct {
   Markets            map[string]Market
}
type Market struct {
   Products            map[string]Product
}
type Product struct {
   ID int
   // 等等...
}

我需要将JSON解组成Events对象。

如果Markets地图不包含Products地图,我会这样做:

var markets map[string]Market
markets = make(map[string]Market)
var e Event
e.Markets = markets
e := json.Unmarshal([]byte(jsonString), &e)

然而,对于每个市场,我还需要make()一个产品,对于每个产品,我可能需要创建进一步的地图等等。

我可以使用一个临时结构体来解决这个问题,循环遍历并对每个键调用make()(参见下面的示例),但这感觉有点凌乱,我相信Go语言应该有一个更简洁的解决方案。

type TmpEvent struct {
   Markets            map[string]TmpMarket
}
type TmpMarket struct {
   // 这里没有地图,可以是空结构体
}
var events Event
var e TmpEvent
var TmpMarkets map[string]TmpMarket
TmpMarkets = make(map[string]TmpMarket)
e.Markets = TmpMarket
e := json.Unmarshal([]byte(jsonString), &e)
for k, _ := range e {
   events[k].Market = make(map[string]Market)
}
// 对于产品也是一样
// 然后我们最终可以解组成原始的`Event`结构体

如果这个问题之前已经回答过了,我很抱歉,但我找不到相关内容。

英文:

I'm pretty sure this can be done with multiple structs (some temporary without the maps) but I'm unsure if there is a nicer way of doing things.

Basically say I have the following structs:

type Event struct {
   Markets            map[string]Market
}
type Market struct {
   Products            map[string]Product
}
type Product struct {
   ID int
   // etc ... 
}

And I need to unmarshal json into the Events object.

If the Markets map didn't contain the Products map, I would do it like this:

var markets map[string]Market
markets = make(map[string]Market)
var e Event
e.Markets = markets
e := json.Unmarshal([]byte(jsonString), &e)

However for each market I also need to make() a Product, and for each Product I may need to create further maps etc.

I could solve this using a temporary struct, looping through and for each key calling make() (see below example) but this feels a little messy and I'm pretty sure golang would have a cleaner solution.

type TmpEvent struct {
   Markets            map[string]TmpMarket
}
type TmpMarket struct {
   // No map here, could be empty struct
}
var events Event
var e TmpEvent
var TmpMarkets map[string]TmpMarket
TmpMarkets = make(map[string]TmpMarket)
e.Markets = TmpMarket
e := json.Unmarshal([]byte(jsonString), &e)
for k, _ := range e {
   events[k].Market = make(map[string]Market)
}
// same for Product
// Then we can finally Unmarshal into original `Event` struct

Sorry if its been answered before but I couldn't find anything.

答案1

得分: 1

如果你只是想将数据解组成Go结构体,以下代码可以实现:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
)

type (
	Event struct {
		Markets map[string]Market
	}
	Market struct {
		Products map[string]Product
	}
	Product struct {
		ID int
	}
)

func main() {
	content, err := ioutil.ReadFile("./data.json")
	if err != nil {
		panic(err)
	}

	var event Event
	if err := json.Unmarshal(content, &event); err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", event)
}

给定以下data.json作为输入:

{
  "markets": {
    "foo": {
      "products": {
        "widget": {
          "id": 1
        },
        "gizmo": {
          "id": 2
        }
      }
    },
    "bar": {
      "products": {
        "doodad": {
          "id": 3
        },
        "thingy": {
          "id": 4
        }
      }
    }
  }
}

上述代码的输出结果为:

{Markets:map[bar:{Products:map[doodad:{ID:3} thingy:{ID:4}]} foo:{Products:map[gizmo:{ID:2} widget:{ID:1}]}]}
英文:

If you're just trying to unmarshal the data into Go structs, the following works:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
)

type (
	Event struct {
		Markets map[string]Market
	}
	Market struct {
		Products map[string]Product
	}
	Product struct {
		ID int
	}
)

func main() {
	content, err := ioutil.ReadFile("./data.json")
	if err != nil {
		panic(err)
	}

	var event Event
	if err := json.Unmarshal(content, &event); err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", event)
}

Given this data.json as input:

{
  "markets": {
    "foo": {
      "products": {
        "widget": {
          "id": 1
        },
        "gizmo": {
          "id": 2
        }
      }
    },
    "bar": {
      "products": {
        "doodad": {
          "id": 3
        },
        "thingy": {
          "id": 4
        }
      }
    }
  }
}

The above code outputs:

{Markets:map[bar:{Products:map[doodad:{ID:3} thingy:{ID:4}]} foo:{Products:map[gizmo:{ID:2} widget:{ID:1}]}]}

huangapple
  • 本文由 发表于 2022年8月5日 06:03:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/73242634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定