Golang将JSON转换为切片的映射,映射本身包含切片(无需类型)

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

Golang JSON to Slice of Maps of Maps themselves Containing Slices (without Types)

问题

我有一个名为config.json的文件,格式如下:

  1. {
  2. "recordType1": [
  3. "field1", "field2", "field3", "field4", "field5"
  4. ],
  5. "recordType2": [
  6. "field1", "field2", "field3", "field4", "field5", "field6", "field7"
  7. ]
  8. }

如果可能的话,我想将其转换为一个切片(slice)的映射(map),其中每个映射本身是一个单独的键(key),而值(value)是一个切片。

我可以手动完成这个操作,像这样:

  1. package main
  2. import "fmt"
  3. func main() {
  4. m := make(map[string][]string, 0)
  5. m2 := make(map[string][]string, 0)
  6. sliceOfMaps := make([]map[string][]string, 0)
  7. m["recordType1"] = []string{"field1", "field2", "field3"}
  8. m2["recordType2"] = []string{"field1", "field2", "field3", "field4", "field5"}
  9. sliceOfMaps = append(sliceOfMaps, m, m2)
  10. fmt.Println(m)
  11. fmt.Println(m2)
  12. fmt.Println(sliceOfMaps)
  13. }

相反,我想对config.json的内容调用json.Unmarshal,将该JSON解析为相同的结构。

我尝试过以下方法:

  1. package main
  2. import (
  3. "fmt"
  4. "encoding/json"
  5. "io/ioutil"
  6. "log"
  7. )
  8. func main() {
  9. file, err := ioutil.ReadFile("config/config.json")
  10. if err != nil {
  11. log.Fatal("读取文件错误:", err)
  12. }
  13. var sliceOfMaps []map[string][]string
  14. sliceOfMaps = make([]map[string][]string, 0)
  15. err = json.Unmarshal(file, &sliceOfMaps)
  16. if err != nil {
  17. log.Fatal("解析JSON错误", err)
  18. }
  19. fmt.Println(sliceOfMaps)
  20. }

这会产生错误:

  1. 解析JSON错误:json: cannot unmarshal object into Go value of type []map[string][]string

非常感谢您的帮助,欢迎提出澄清问题。谢谢。

英文:

I have a config.json with the following format:

  1. {
  2. "recordType1": [
  3. "field1", "field2", "field3", "field4", "field5"
  4. ],
  5. "recordType2": [
  6. "field1", "field2", "field3", "field4", "field5", "field6", "field7"
  7. ]
  8. }

If possible, I'd like to convert this to a slice of maps, where each map is itself is a single 'key', and the 'value' is a slice.

I can accomplish this manually like:

  1. package main
  2. import ("fmt")
  3. func main() {
  4. m := make(map[string][]string, 0)
  5. m2 := make(map[string][]string, 0)
  6. sliceOfMaps := make([]map[string][]string, 0)
  7. m["recordType1"] = []string{"field1", "field2", "field3"}
  8. m2["recordType2"] = []string{"field1", "field2", "field3", "field4", "field5"}
  9. sliceOfMaps = append(sliceOfMaps, m, m2)
  10. fmt.Println(m)
  11. fmt.Println(m2)
  12. fmt.Println(sliceOfMaps)
  13. }

Instead, I'd like to invoke json.Unmarshal on the contents of config.json to parse that json into the very same structure.

What I've tried so far:

  1. package main
  2. import (
  3. "fmt"
  4. "encoding/json"
  5. "io/ioutil"
  6. "log"
  7. )
  8. func main() {
  9. file, err := ioutil.ReadFile("config/config.json")
  10. if err != nil {
  11. log.Fatal("Err Reading File:", err)
  12. }
  13. var sliceOfMaps []map[string][]string
  14. sliceOfMaps = make([]map[string][]string, 0)
  15. err = json.Unmarshal(file, &sliceOfMaps)
  16. if err != nil {
  17. log.Fatal("Err Parsing JSON", err)
  18. }
  19. fmt.Println(sliceOfMaps)
  20. }

This produces error:

  1. Err Parsing JSONjson: cannot unmarshal object into Go value of type []map[string][]string

Any assistance is greatly appreciated, clarifying questions welcome. Thanks.

答案1

得分: 4

你的JSON输入和"manual"示例都使用了切片的映射,而不是映射的切片。将目标类型更改为map[string][]string,然后你就可以运行了:

  1. package main
  2. import (
  3. "fmt"
  4. "encoding/json"
  5. )
  6. var file = []byte(`{
  7. "recordType1": [
  8. "field1", "field2", "field3", "field4", "field5"
  9. ],
  10. "recordType2": [
  11. "field1", "field2", "field3", "field4", "field5", "field6", "field7"
  12. ]
  13. }`)
  14. func main() {
  15. output := map[string][]string{}
  16. if err := json.Unmarshal(file, &output); err != nil {
  17. panic(err)
  18. }
  19. fmt.Println(output)
  20. }

产生以下输出:

  1. map[recordType1:[field1 field2 field3 field4 field5] recordType2:[field1 field2 field3 field4 field5 field6 field7]]

Playground链接

英文:

Both your JSON input, and your "manual" example are using maps of slices, not slices of maps. Change your target type to map[string][]string and you should be good to go:

  1. package main
  2. import (
  3. "fmt"
  4. "encoding/json"
  5. )
  6. var file = []byte(`{
  7. "recordType1": [
  8. "field1", "field2", "field3", "field4", "field5"
  9. ],
  10. "recordType2": [
  11. "field1", "field2", "field3", "field4", "field5", "field6", "field7"
  12. ]
  13. }`)
  14. func main() {
  15. output := map[string][]string{}
  16. if err := json.Unmarshal(file, &output); err != nil {
  17. panic(err)
  18. }
  19. fmt.Println(output)
  20. }

Produces the following output:

  1. map[recordType1:[field1 field2 field3 field4 field5] recordType2:[field1 field2 field3 field4 field5 field6 field7]]

Playground link.

huangapple
  • 本文由 发表于 2017年8月17日 01:04:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/45719297.html
匿名

发表评论

匿名网友

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

确定