Elixir: Как преобразовать список ключевых слов в карту?
У меня есть список ключевых слов из изменений набора элементов Ecto, которые я хотел бы преобразовать в карту, чтобы парсер Poison JSON мог корректно выводить список ошибок проверки в формате JSON.
Итак, я получаю список ошибок следующим образом:
[:topic_id, "can't be blank", :created_by, "can't be blank"]
... и я бы хотел получить такую карту ошибок:
%{topic_id: "can't be blank", created_by: "can't be blank"}
В качестве альтернативы, если бы я мог преобразовать его в список строк, я тоже мог бы это использовать.
Лучший способ выполнить любую из этих задач?
Ответы
Ответ 1
У вас там нет списка ключевых слов, это просто список с каждым нечетным элементом, представляющим ключ и каждый четный элемент, представляющий значение.
Разница заключается в следующем:
[: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/2 и Enum.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/3
. Например:
[:topic_id, "can't be blank", :created_by, "can't be blank"]
|> Enum.chunk(2)
|> Enum.into(%{}, fn [key, val] -> {key, val} end)
Ответ 3
Еще один способ сделать это - использовать понимание списка:
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