Nested data structures in Go – Python equivalent

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

Nested data structures in Go - Python equivalent

问题

我可以很容易地在Python中创建这个数据结构:

  1. data = {'Locations': [],
  2. 'Dates': [],
  3. 'Properties': [{'key': 'data1', 'value': 'data2'}],
  4. 'Category': 'all'}

然后可以很容易地将其转换为JSON格式。例如:

  1. import json
  2. print(json.dumps(data))

输出结果为:

  1. {"Category": "all", "Dates": [], "Locations": [], "Properties": [{"value": "data2", "key": "data1"}]}

然而,我正在尝试在Go语言中创建相同的结构并将其转换为JSON,但是我无法让结构包含应该包围属性元素的方括号。

  1. import (
  2. "fmt"
  3. "encoding/json"
  4. )
  5. func main() {
  6. data := map[string]interface{}{
  7. "Offset": "0",
  8. "Properties": map[string]string{"value": "data2", "key": "data1"},
  9. "Category": "all",
  10. "Locations": []string{},
  11. "Dates": []string{},
  12. }
  13. data_json, _ := json.Marshal(data)
  14. fmt.Println(string(data_json))
  15. }

输出结果为:

  1. {"Category":"all","Dates":[],"Locations":[],"Offset":"0","Properties":{"key":"data1","value":"data2"}}

这是一个演示:http://play.golang.org/p/49Kytg6v_C

英文:

I can create this data structure in Python really easily:

  1. data = {'Locations': [],
  2. 'Dates': [],
  3. 'Properties': [{'key': 'data1', 'value': 'data2'}],
  4. 'Category': 'all'}

Which can then be marshalled to JSON in Python just as easily. e.g.

  1. print json.dumps(data)
  2. {"Category": "all", "Dates": [], "Locations": [], "Properties": [{"value": "data2", "key": "data1"}]}

However, I'm tearing my hair out trying to create the same structure then convert it to JSON in Go. Go looks to be very promising and just what I need for creating cross platform applications, but boy this stuff seems to be frustratingly difficult.

This is what I've tried, however I cant get the structure to include the square brackets that should surround the properties element.

  1. import (
  2. "fmt"
  3. "encoding/json"
  4. )
  5. func main() {
  6. data := map[string]interface{}{"Offset": "0", "Properties": map[string]string{"value": "data2", "key": "data1"}, "Category": "all", "Locations": []string{}, "Dates": []string{} }
  7. data_json, _ := json.Marshal(data)
  8. fmt.Println(string(data_json))
  9. }

Which outputs:

  1. {"Category":"all","Dates":[],"Locations":[],"Offset":"0","Properties":{"key":"data1","value":"data2"}}

Heres a demo: http://play.golang.org/p/49Kytg6v_C

答案1

得分: 2

你只需要创建一个 map[string]string 的切片:

  1. data := map[string]interface{}{
  2. "Offset": "0",
  3. "Properties": []map[string]string{{"value": "data2", "key": "data1"}},
  4. "Category": "all",
  5. "Locations": []string{},
  6. "Dates": []string{},
  7. }

playground

英文:

You just need to create a slice of map[string]string:

  1. data := map[string]interface{}{
  2. "Offset": "0",
  3. "Properties": []map[string]string{{"value": "data2", "key": "data1"}},
  4. "Category": "all",
  5. "Locations": []string{},
  6. "Dates": []string{},
  7. }

<kbd>playground</kbd>

答案2

得分: 2

虽然 OneOfOne 的解决方案在字面上是可行的,但由于 Go 的静态类型特性,你可能想要使用结构体。

  1. // `json:"stuff"` 会在读取或写入 JSON 时使用该 JSON 标签。
  2. type Property struct {
  3. Key string `json:"key"`
  4. Val string `json:"value"`
  5. }
  6. // ,omitempty 允许在写入 JSON 时忽略空字符串 "",
  7. // 我在这里加上它是因为你的 JSON 示例中的一个字段没有 Offset 字段
  8. // 你也可以对其他字段使用它。
  9. type MyType struct {
  10. Offset string `json:",omitempty"`
  11. Properties []Property
  12. Category string
  13. Locations []string
  14. Dates []string
  15. }

当然,你也可以考虑使用内置的或自定义的 Go 类型来表示其中一些字段,例如在 Dates 字段中使用 []time.Time。这样做会使得随意读取/写入任意 JSON 数据变得更加困难,但由于你需要在某个地方编写一些逻辑来解释这些字段,在 Go 中通常更合理的做法是大部分时间将其视为一个结构体。

要读取/写入 JSON,你可以这样做:

  1. import "encoding/json"
  2. //...
  3. stuff := MyType{}
  4. json.Unmarshal(myJsonData, &stuff)
  5. // 现在 stuff 是 { [{data1 data2}] all [] []}
  6. out, _ := json.Marshal(stuff)
  7. // string(out) 现在是 { "Properties":[{"key":"data1","value":"data2"}],
  8. // "Category":"all","Locations":[],"Dates":[]}

Playground: http://play.golang.org/p/jIHgXmY13R

英文:

While OneOfOne's solution works in a literal sense, with Go's static typing you likely want a struct.

  1. // The `json:&quot;stuff&quot;` will cause it to use that json tag when reading or writing json.
  2. type Property struct {
  3. Key string `json:&quot;key&quot;`
  4. Val string `json:&quot;value&quot;`
  5. }
  6. // ,omitempty allows it to ignore the empty string &quot;&quot; when writing json,
  7. // I put this here because one of your json examples had no Offset field
  8. // you can do this with other fields too.
  9. type MyType struct {
  10. Offset string `json:&quot;,omitempty&quot;`
  11. Properties []Property
  12. Category string
  13. Locations []string
  14. Dates []string
  15. }

Of course, you could also consider using built-in or custom Go types for some of those fields, such as using a []time.Time for the Dates field. This makes it more difficult to just read/write arbitrary json ad-hoc or on the fly, but since you need to have some logic somewhere to interpret those fields, in Go it generally makes much more sense to treat it as a struct most of the time.

To read in/put out the json, you would then do

  1. import &quot;encoding/json&quot;
  2. //...
  3. stuff := MyType{}
  4. json.Unmarshal(myJsonData, &amp;stuff)
  5. // stuff is now { [{data1 data2}] all [] []}
  6. out,_ := json.Marshal(stuff)
  7. // string(out) is now {&quot;Properties&quot;:[{&quot;key&quot;:&quot;data1&quot;,&quot;value&quot;:&quot;data2&quot;}],
  8. // &quot;Category&quot;:&quot;all&quot;,&quot;Locations&quot;:[],&quot;Dates&quot;:[]}

Playground: http://play.golang.org/p/jIHgXmY13R

huangapple
  • 本文由 发表于 2014年12月18日 07:53:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/27536965.html
匿名

发表评论

匿名网友

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

确定