Elixir-JasonHelpers-如何将关键字列表发送到json_map?

我有一个要转换为json并保留键顺序的数据结构。

例如: File(FILE_NAME).readLines().fold(StringBuilder()){ builder,next -> builder.appendln(next) }.also { mEditText.setText(it.toString()) } 应转换为%{ x: 1,a: 5}

中毒完全没有问题。但是当我升级到Jason时,它更改为"{\"x\": 1,\"a\": 5}"

所以我使用JasonHelpers json_map来保留这样的顺序:

"{\"a\": 5,\"x\": 1}"

它将创建具有正确顺序的片段。

但是,当我使用变量执行此操作时:

Jason.Helpers.json_map([x: 1,a: 5])

我有一个错误:

list = [x: 1,a: 5]
Jason.Helpers.json_map(list)

问题::如何将预先计算的列表传递到** (Protocol.UndefinedError) protocol Enumerable not implemented for {:list,[line: 15],nil} of type Tuple. .... 中?

计算很复杂,所以我不想仅使用json_map重复代码,而是使用返回列表的函数。

yangshegnhui 回答:Elixir-JasonHelpers-如何将关键字列表发送到json_map?

json_map/1是一个宏,来自其文档:

  

使用编译时关键字对JSON映射进行编码。

它旨在在编译时编译JSON,这就是为什么它不适用于您的运行时变量的原因。

added to the Jason library a year ago支持对关键字列表进行编码,但是看起来还没有被强制转换为十六进制。我设法通过从github提取最新代码来使其工作:

defp deps do
  [{:jason,git: "https://github.com/michalmuskala/jason.git"}]
end

然后通过创建实现Jason.Encoder的结构(由Jason作者改编自this solution):

defmodule OrderedObject do
  defstruct [:value]

  def new(value),do: %__MODULE__{value: value}

  defimpl Jason.Encoder do
    def encode(%{value: value},opts) do
      Jason.Encode.keyword(value,opts)
    end
  end
end

现在我们可以使用有序键对对象进行编码:

iex(1)> Jason.encode!(OrderedObject.new([x: 1,a: 5]))
"{\"x\":1,\"a\":5}"
,

我不知道这是公共API的一部分还是只是实现细节,但在为结构实现Jason.Encoder协议时,您似乎可以控制顺序。

假设您已经定义了Ordered结构:

defmodule Ordered do
  @derive {Jason.Encoder,only: [:a,:x]}
  defstruct [:a,:x]
end

如果对结构进行编码,则“ a”键将在“ x”键之前:

iex> Jason.encode!(%Ordered{a: 5,x: 1})
"{\"a\":5,\"x\":1}"

我们将传递给:only选项的键重新排序:

defmodule Ordered do
  @derive {Jason.Encoder,only: [:x,:a]}
  defstruct [:a,:x]
end

如果我们现在对结构进行编码,则“ x”键将在“ a”键之前:

iex> Jason.encode!(%Ordered{a: 5,x: 1})
"{\"x\":1,\"a\":5}"
本文链接:https://www.f2er.com/3150404.html

大家都在问