使用Poison将Map编码为JSON时如何排序键?

7
为了阅读方便,我希望在json文件中有特定的键顺序。
我知道map的键没有任何顺序,因此我们不应该依赖它,但由于Poison无法编码proplists,我不知道如何实现这一点。
iex(1)> %{from: "EUR", to: "USD", rate: 0.845} |> Poison.encode!
"{\"to\":\"USD\",\"rate\":0.845,\"from\":\"EUR\"}"

The result I would like is :

"{\"from\":\"EUR\", \"to\":\"USD\", \"rate\":0.845}"

我该使用哪种结构才能使用Poison实现这个功能?
1个回答

2

你确定要这样做吗?可能最好的方法是为你的map定义一个结构体,然后为该结构体实现Poison编码协议。

它可能看起来像这样...

defmodule Currency do
    defstruct from: "", to: "", rate: 0
end

然后在您的项目中某个位置实现该协议。

defimpl Poison.Encoder, for: Currency do
  def encode(%Currency{from: from, to: to, rate: rate}, _options) do
    """
      {"from": #{from}, "to": #{to}, "rate": #{rate}}
    """
  end
end

然后

Poison.encode!(%Currency{from: "USD", to: "EUR", rate: .845})

尽管如此,我真的非常不建议这样做。有序映射始终是一个糟糕的想法,并且会导致一些非常脆弱和令人困惑的行为。

考虑使用实际有序的东西,比如一个列表中嵌套列表。


1
我在某种程度上也有这个要求。我们将许多微小的JSON对象(tick数据)存储在纯文本文件中。通过以某种特定的方式排序字段,可以使tick数据可排序,而无需解包/解码JSON,从而节省大量处理能力,并且使使用编码数据的简单字符串比较成为可能。但是,我通常会同意您的观点,认为这可能不应轻易进行。 - Anders Hansson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接