2015-07-21 88 views
18

我有一个Ecto changeset错误的关键字列表我想要转换为一个映射,以便毒药JSON解析器可以正确输出JSON格式的验证错误列表。Elixir:如何将关键字列表转换为地图?

所以我得到的错误列表如下:

[:topic_id, "can't be blank", :created_by, "can't be blank"] 

...我想获得地图的错误,像这样:

%{topic_id: "can't be blank", created_by: "can't be blank"} 

或者,如果我能将其转换为字符串列表,我也可以使用它。

完成这些任务的最佳方法是什么?

回答

34

你在那里没有关键字列表,它只是一个列表,每个奇数元素表示一个键,每个偶数元素表示一个值。

的区别是:

[:topic_id, "can't be blank", :created_by, "can't be blank"] # List 
[topic_id: "can't be blank", created_by: "can't be blank"] # Keyword List 

关键字列表可以变成使用地图Enum.into/2

Enum.into([topic_id: "can't be blank", created_by: "can't be blank"], %{}) 

由于你的数据结构是一个列表,你可以使用Enum.chunk/2Enum.reduce/3

将其转换
[:topic_id, "can't be blank", :created_by, "can't be blank"] 
|> Enum.chunk(2) 
|> Enum.reduce(%{}, fn ([key, val], acc) -> Map.put(acc, key, val) end) 

您可以阅读关于关键字列表的更多信息,请致电http://elixir-lang.org/getting-started/maps-and-dicts.html

+2

更多关于这种使用情况下,我不能试一下的权利,但我有,你应该能够在最后一个例子减少'的感觉[...] | > Enum.chunk(2)|> Enum.into(%{})' –

+0

啊,我错过了列表和关键字列表之间的区别。谢谢! –

+0

我也遇到与OP相同的问题,只有我相信Changeset已经改变了它的实现。 ATOW变更集错误_is_是关键字列表,例如'[field_1:{“is invalid”,[type:Ecto.UUID]},field_2:{“can not be blank”,[]}]'。我可以用'error_map = Enum.into(changeset.errors,%{})'这个答案的'Enum.into'方法转换成地图。作为一张地图,我可以通过'{err_msg,_type} = Map.fetch!(error_map,:field_1)'得到我的消息'。 – ibgib

7

另一种方法是将Enum.chunk/2Enum.into/3结合使用。例如:

[:topic_id, "can't be blank", :created_by, "can't be blank"] 
|> Enum.chunk(2) 
|> Enum.into(%{}, fn [key, val] -> {key, val} end) 
5

另一种方式做到这一点是通过使用列表理解的:

iex> list = [:topic_id, "can't be blank", :created_by, "can't be blank"] 
iex> map = for [key, val] <- Enum.chunk(list, 2), into: %{}, do: {key, val} 
%{created_by: "can't be blank", topic_id: "can't be blank"} 

除此之外,您还可以将您的列表,以关键字列表:

iex> klist = for [key, val] <- Enum.chunk(list, 2), do: {key, val} 
[topic_id: "can't be blank", created_by: "can't be blank"] 

这可能是在某些情况下也是有用的。

您可以阅读http://elixir-lang.org/getting-started/comprehensions.html#results-other-than-lists