我要做的是用最短的代码构建Elixir映射,并使用与键相同的变量名称,并将变量的值作为映射的值。示例:
first_name = "Michael"
last_name = "Blomponets"
地图看起来像
%{
"first_name" => "Michael",
"last_name" => "Blomponets",
}
答案 0 :(得分:2)
最好的方法是明确声明地图的确切位置。但是,如果您绝对想要速记(我不推荐这样做),则可以使用宏来完成它:
defmodule MapShorthand do
@doc """
Allows for map shorthand.
iex> ~~~%{a, b: %{c: d}} = %{a: 3, b: %{c: 4}}
%{a: 3, b: %{c: 4}}
iex> {a, d}
{3, 4}
iex> ~~~%{a, b: %{c: d}}
%{a: 3, b: %{c: 4}}
"""
defmacro ~~~map do
Macro.postwalk(map, fn
{:%{}, meta, pairs} ->
pairs =
Enum.map(pairs, fn
value = {key, _meta, context} when is_atom(key) and is_atom(context) ->
{key, value}
pair ->
pair
end)
{:%{}, meta, pairs}
ast ->
ast
end)
end
end
它进入您的地图,并且在任何地方看到变量而不是{key,value}对的地方,都会创建一个{key,value}对,其中key是变量的名称。您也可以根据需要命名宏。我只是和一元运算符一起去的。
然后您可以使用JavaScript样式的缩写:
iex> import MapShorthand, only: [~~~: 1]
MapShorthand
iex> ~~~%{name, age: %{years: age}} = %{name: "Ron", age: %{years: 42, months: 8}}
%{age: %{months: 8, years: 42}, name: "Ron"}
iex> ~~~%{name, age}
%{age: 42, name: "Ron"}
答案 1 :(得分:1)
写某人库的人的建议,然后认为这是个坏主意:
https://andrealeopardi.com/posts/a-story-of-regret-and-retiring-a-library-from-hex/
short_maps为Elixir增添了魔力。当某人在他们的代码库中使用short_maps时,它会迫使阅读该代码库的人员(甚至是经验丰富的Elixir开发人员)都知道这一点。作为一种语法功能,它确实在您的面前,如果您不熟悉它,它将使代码难以阅读。原子键和字符串键之间的区别也不明显,其结果是使代码看起来更加混乱。
答案 2 :(得分:0)
要回应其他人的说法,通常不值得以拥有代码库特有的自定义语言扩展(也称为Haskell问题)为代价引入自定义宏。
但是,在特定情况下,您需要将所有变量导出到映射或关键字列表中,则可以使用binding/1
。
iex(1)> a = 1
1
iex(2)> b = 2
2
iex(3)> binding()
[a: 1, b: 2]
iex(4)> Map.new(binding())
%{a: 1, b: 2}
我认为在宏和测试设置块中只有两个位置。
在测试的情况下可以帮助减少样板:
setup do
author = insert(:author)
post = insert(:post, author: author)
comment = insert(:comment, post: post)
[author: author, post: post, comment: comment]
end
成为:
setup do
author = insert(:author)
post = insert(:post, author: author)
comment = insert(:comment, post: post)
binding()
end
与所有事物一样,请使用您的判断力:)。