elliotchance / orderedmap

🔃 An ordered map in Go with amortized O(1) for Set, Get, Delete and Len.
MIT License
817 stars 62 forks source link

`json.Marshal` — doesn't work #12

Open RubaXa opened 4 years ago

RubaXa commented 4 years ago

Hi,

I try convert OrderedMap to json, but receive empty object :/

package main

import (
    "fmt"
    "encoding/json"
    "github.com/elliotchance/orderedmap"
)

func main() {
    m := orderedmap.NewOrderedMap()

    m.Set("foo", "bar")
    m.Set("qux", 1.23)
    m.Set(123, true)

    b, err := json.Marshal(m)
    if err != nil {
        fmt.Println("error:", err)
    }

    fmt.Println("result:", string(b)) // "result: {}" ⚠️
}

https://play.golang.org/p/UFER3tR6uPA

elliotchance commented 4 years ago

This is because marshalling has not been implemented for orderedmap.

I'm not sure what this would actually look like because it must be reasonable that the order would also be retained in the data structure. So simply using a JSON object would not be sufficient.

Since there are multiple ways marshalling and unmarshalling could work so it's best to leave it up to the implementation. Here is one example that might suit your needs:

https://play.golang.org/p/LjOrp4k6lqf

abusizhishen commented 4 years ago

This is because marshalling has not been implemented for orderedmap.

I'm not sure what this would actually look like because it must be reasonable that the order would also be retained in the data structure. So simply using a JSON object would not be sufficient.

Since there are multiple ways marshalling and unmarshalling could work so it's best to leave it up to the implementation. Here is one example that might suit your needs:

https://play.golang.org/p/LjOrp4k6lqf

marshaling and unmarshaling may cause unexpected issue, like int type will be marshal into int64 type in your example https://play.golang.org/p/IjP7E3lRMhT

elliotchance commented 4 years ago

If the order and specific data types must be retained in the serialized value then you will need a more complex marshaller to suit your specific needs.

89trillion-feiyang commented 3 years ago

This is because marshalling has not been implemented for orderedmap.

I'm not sure what this would actually look like because it must be reasonable that the order would also be retained in the data structure. So simply using a JSON object would not be sufficient.

Since there are multiple ways marshalling and unmarshalling could work so it's best to leave it up to the implementation. Here is one example that might suit your needs:

https://play.golang.org/p/LjOrp4k6lqf

The structure after serialization is not what I want.

According to your code result is

[
   [
     "2",
    {
      "a": "2",
      "b": "7"
    }
  ],
  [
    "3",
    {
      "a": "3",
      "b": "1"
    }
  ]
]

Expect:

{
  "2": {
        "a": 3,
        "b": 4
    }
}
elliotchance commented 3 years ago

@89trillion-feiyang - you can serialize it in any format you want. Here's some sample code to produce that: https://play.golang.org/p/tKGpbGCpFbC

Keep in mind some caveats with that:

  1. The order will be lost when serializing (and unserializing). There's no way around that because Go sorts maps for JSON output.
  2. All of your keys must be strings.
89trillion-feiyang commented 3 years ago

@89trillion-feiyang - you can serialize it in any format you want. Here's some sample code to produce that: https://play.golang.org/p/tKGpbGCpFbC

Keep in mind some caveats with that:

  1. The order will be lost when serializing (and unserializing). There's no way around that because Go sorts maps for JSON output.
  2. All of your keys must be strings.

OK. Thanks! I solved it.