json - 使用特定顺序序列化 map

标签 json serialization go

我有一个使用字符串作为键和值的映射。我有一个键数组,用于指定映射值的顺序。

我想将该映射序列化为 JSON,但保持数组中定义的顺序。

这里有一个示例代码:http://play.golang.org/p/A52GTDY6Wx

我想将它序列化为:

{
  "name": "John",
  "age": "20"
}

但是如果我直接序列化 map ,键是按字母顺序排列的:

{      
  "age": "20",
  "name": "John"
}

我可以将它序列化为一个映射数组,从而保持顺序,但是会生成很多不需要的字符:

[
  {
    "name": "John"
  },
  {
    "age": "20"
  }
]

在我的真实代码中,我需要序列化在文本文件中指定的数据库查询的结果,并且我需要维护列顺序。我不能使用结构,因为这些列在编译时是未知的。

编辑:我不需要稍后按指定顺序阅读 JSON。生成的 JSON 旨在供人们阅读,因此我只希望它尽可能具有人类可读性。

我可以使用自定义格式,但 JSON 非常适合我。

谢谢!

最佳答案

您需要在自定义类型上实现json.Marshaler 接口(interface)。这具有在其他结构类型中发挥良好的优势。

抱歉,您总是需要编写一些 JSON 编码代码。

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log"
)

type KeyVal struct {
    Key string
    Val interface{}
}

// Define an ordered map
type OrderedMap []KeyVal

// Implement the json.Marshaler interface
func (omap OrderedMap) MarshalJSON() ([]byte, error) {
    var buf bytes.Buffer

    buf.WriteString("{")
    for i, kv := range omap {
        if i != 0 {
            buf.WriteString(",")
        }
        // marshal key
        key, err := json.Marshal(kv.Key)
        if err != nil {
            return nil, err
        }
        buf.Write(key)
        buf.WriteString(":")
        // marshal value
        val, err := json.Marshal(kv.Val)
        if err != nil {
            return nil, err
        }
        buf.Write(val)
    }

    buf.WriteString("}")
    return buf.Bytes(), nil
}

func main() {
    dict := map[string]interface{}{
        "orderedMap": OrderedMap{
            {"name", "John"},
            {"age", 20},
        },
    }
    dump, err := json.Marshal(dict)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", dump)
}

输出

{"orderedMap":{"name":"John","age":20}}

关于json - 使用特定顺序序列化 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25182923/

相关文章:

javascript - 如何反序列化未知派生类的JavaScript对象

java - Objective-C : Serializing/Archiving issues

php - 按日期对 PHP 中的 json 数组进行排序?

java - 强制 jackson 反序列化为特定的原始类型

javascript - 带有 JSON 数据的 DataTable

java - 保存大型短数组android

javascript - 从 HTML 调用 Golang

go - 404响应后继续循环

exception - 在 golang 中出现 panic error 或其他问题时如何避免影响其他代码

json - 如何使用包含已编码值的 Encodable 在 Swift 中对结构进行编码