json-iterator/go

jsoniter.Marshal makes ordered maps unordered

xiaozhiliaoo opened this issue · 2 comments

func Test_jsoniterMarshal(t *testing.T) {
	m := map[string]int{"c": 3, "a": 1, "b": 2}
	keys := make([]string, 0, len(m))
	for key := range m {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	fmt.Println(m) // map[a:1 b:2 c:3]
	marshal, _ := jsoniter.Marshal(m) // jsoniter "github.com/json-iterator/go" package
	fmt.Println(string(marshal)) // {"c":3,"a":1,"b":2}
}

the map is ordered by sort. but jsoniter.Marshal make the map unordered. but json.Marshal json.Marshal

func Test_jsonMarshal(t *testing.T) {
	m := map[string]int{"c": 3, "a": 1, "b": 2}
	keys := make([]string, 0, len(m))
	for key := range m {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	marshal, _ := json.Marshal(m) // "encoding/json" package
	fmt.Println(string(marshal)) //{"a":1,"b":2,"c":3}
}

You try to marshal an umsorted map m. The result is also unsorted which is ok.
May be you need to sort m first before marshalling.

...

sort.Strings(keys)
sort.Strings(m)
// marshal m
// and then do the check/ print
...

the map is ordered by sort

This was a surprise to me, but you are right: the built-in encoding/json package documentation says:

"Map values encode as JSON objects... The map keys are sorted and used as JSON object keys..."

May be you need to sort m first before marshalling.

You can't sort a map in Go. Maps have no guaranteed order. The only way to do it is to copy the key-value pairs into some other data structure.