与Enum.map的深度合并映射

时间:2018-02-13 10:41:36

标签: elixir

我有这个功能:

defmodule TestQuery do

  def build_query() do
    Enum.map(["test1", "test2", "hello"], fn item ->
      query(item)
    end)
  end

  def query(item) do
    case item do
      "test1" -> %{"test1" => 1}
      "test2" -> %{"test2" => 2}
      "hello" -> %{"hello" => 3}
    end
  end

end

build_query返回一个这样的地图列表:

iex(2)> TestQuery.build_query
[%{"test1" => 1}, %{"test2" => 2}, %{"hello" => 3}]

但是有没有办法像这样返回一张地图?

%{"test1" => 1, "test2" => 2, "hello" => 3}

我应该使用其他方法代替Enum.map吗?

我知道我可以在列表Map.reduce和Map.merge列表之后但是我想知道它是否可以一步完成。

1 个答案:

答案 0 :(得分:2)

如果query/1始终返回一对键/值,则可以将forinto: %{}一起使用,并从query/1返回一个元组:

defmodule TestQuery do
  def build_query do
    for item <- ["test1", "test2", "hello"], into: %{}, do: query(item)
  end

  def query(item) do
    case item do
      "test1" -> {"test1", 1}
      "test2" -> {"test2", 2}
      "hello" -> {"hello", 3}
    end
  end
end

IO.inspect TestQuery.build_query()

输出:

%{"hello" => 3, "test1" => 1, "test2" => 2}

如果它可以返回多个项目,您可以将reduce步骤与地图合并,并在一个通道中执行,如下所示:

defmodule TestQuery do
  def build_query do
    Enum.reduce(["test1", "test2", "hello"], %{}, fn item, acc ->
      Map.merge(acc, query(item))
    end)
  end

  def query(item) do
    case item do
      "test1" -> %{"test1" => 1}
      "test2" -> %{"test2" => 2}
      "hello" -> %{"hello" => 3}
    end
  end
end

IO.inspect TestQuery.build_query()

输出与上述相同。