I want to prevent alphabetically reordering at Marshal. My script is below. {"key3": "value3", "key2": "value2", "key1": "value1"}
is reordered to {"key1":"value1","key2":"value2","key3":"value3"}
by Marshal. I thought this may be close issue. But I could not solve my issue. Is there way to solve this?
package main
import (
"encoding/json"
"fmt"
)
func main() {
obj := `{"key3": "value3", "key2": "value2", "key1": "value1"}`
var o map[string]interface{}
json.Unmarshal([]byte(obj), &o)
fmt.Println(o)
r, _ := json.Marshal(o)
fmt.Println(string(r))
}
play.golang.org
fmt.Println(o)
is map[key3:value3 key2:value2 key1:value1]
.fmt.Println(string(r))
is {"key1":"value1","key2":"value2","key3":"value3"}
.Thank you so much for your time. And I'm sorry for my immature question.
You can preserve the order like this:
type OrderedMap struct {
Order []string
Map map[string]string
}
func (om *OrderedMap) UnmarshalJSON(b []byte) error {
json.Unmarshal(b,&om.Map)
index:=make(map[string]int)
for key:=range om.Map {
om.Order=append(om.Order,key)
esc,_:=json.Marshal(key) //Escape the key
index[key]=bytes.Index(b,esc)
}
sort.Slice(om.Order, func(i,j int) bool { return index[om.Order[i]]<index[om.Order[j]] })
return nil
}
func (om OrderedMap) MarshalJSON() ([]byte, error) {
var b []byte
buf:=bytes.NewBuffer(b)
buf.WriteRune('{')
l:=len(om.Order)
for i,key:=range om.Order {
km,err:=json.Marshal(key)
if err!=nil { return nil,err }
buf.Write(km)
buf.WriteRune(':')
vm,err:=json.Marshal(om.Map[key])
if err!=nil { return nil,err }
buf.Write(vm)
if i!=l-1 { buf.WriteRune(',') }
fmt.Println(buf.String())
}
buf.WriteRune('}')
fmt.Println(buf.String())
return buf.Bytes(),nil
}
Playground: https://play.golang.org/p/TxenZEuy_u0
Please note that json spec says objects are unordered, which means other client may not respect the order you preserve.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With