是否有一个用于使用与变量相同的键和值来构建映射的图?

问题描述 投票:0回答:2

[我想做的是用最短的代码构建Elixir映射,并使用与键相同的变量名称,并将变量的值作为映射的值。示例:

    first_name = "Michael"
    last_name = "Blomponets"

地图看起来像

%{
    "first_name" => "Michael",
    "last_name" => "Blomponets",
}
elixir
2个回答
1
投票

最佳方法是明确声明地图的确切位置。但是,如果您绝对想要速记(我不建议这样做),则可以使用宏来完成它:

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"}

0
投票

来自写一个库的人的建议,然后认为这是一个坏主意:

https://andrealeopardi.com/posts/a-story-of-regret-and-retiring-a-library-from-hex/

short_maps为Elixir增添了魔力。当某人在他们的代码库中使用short_maps时,它会迫使阅读该代码库的人员(甚至是经验丰富的Elixir开发人员)都知道这一点。作为一种语法功能,它确实在您的面前,如果您不熟悉它,它将使代码难以阅读。原子键和字符串键之间的区别也不明显,其结果是使代码看起来更加模糊。

© www.soinside.com 2019 - 2024. All rights reserved.