【问题标题】:Elixir - pattern match on map structure, rather than keyElixir - 地图结构上的模式匹配,而不是键
【发布时间】:2018-02-25 20:49:31
【问题描述】:

在 Elixir 中,我有一个嵌套映射列表,每个映射都具有相同的基本结构 - 例如:

nested_map_list = [
    %{foo: %{test: "Hi"}},
    %{bar: %{test: "Hello"}},
    %{baz: %{test: "Hey"}}
]

所以他们每个人在上层都有不同的键,但在嵌套映射中是相同的键。有没有一种方法可以遍历这个列表,以便每次迭代都访问嵌套映射,而不管上层的键是什么?

为了说明我的意思,请考虑以下伪代码:

Enum.each(nested_map_list, fn(%{_key: nested_data}) -> IO.puts nested_data.test end)

> "Hi"
> "Hello"
> "Hey"

非常感谢!

【问题讨论】:

    标签: elixir


    【解决方案1】:

    虽然其他答案都是正确的,但我会在这里使用for 和模式匹配,如下所示:

    iex(1)> nested_map_list = [
    ...(1)>   %{foo: %{test: "Hi"}},
    ...(1)>   %{bar: %{test: "Hello"}},
    ...(1)>   %{baz: %{test: "Hey"}}
    ...(1)> ]
    iex(2)> for x <- nested_map_list, {_, %{test: test}} <- x, do: IO.puts(test)
    Hi
    Hello
    Hey
    

    【讨论】:

    • 这个解决方案当然应该被标记为最佳答案。
    • @mudasobwa for 更好看,但我总是发现reduce 更容易理解正在发生的事情。另外,for 更慢。在这种情况下,这是一项非常简单的任务,如果您在具有 10k 个键的映射中同时使用这两种方法,for 会花费 + 两倍的时间。如果你对过滤做任何更复杂的事情......
    • @MicaelNussbaumer 关于“for 更慢”的任何证据?不应该,因为它令人惊讶地编译为减速器。
    • @mudasobwa 是的,只需对它们进行基准测试。有什么方法可以在这里发送消息/聊天吗?
    • @dogbert 啊,是的!我正在寻找一种模式匹配的方法。没有意识到for 会允许这样做。
    【解决方案2】:

    Enum.reduceEnum.each 和朋友可以迭代 key=&gt;value 对,所以在这种情况下,我可能会将其分为两个函数,一个在列表成员上迭代,一个在列表成员上迭代地图。如果您想存储结果(通常是您想要的),则需要减少而不是 Enum.each

    Enum.each(nested_map_list, fn(element) ->
        Enum.each(element, fn({_k, value}) ->
            IO.inspect(value[:test])
        end)
    end)
    

    【讨论】:

      【解决方案3】:

      哦,这是我刚刚整理出来的一种可能性 -

      Enum.each(nested_map_list, fn(nested_data) ->
        [{key, value}] = Map.to_list(nested_data)
        IO.puts value.test
      end)
      

      接受任何更好的答案。

      【讨论】:

      • 对于“更漂亮”的解决方案,这取决于您真正想要实现的目标,通常一般的问题不会给您最好的答案,因为这些取决于。如果您只想打印值...嗯。如果你想要一些递归的东西,能够遍历一个内部可能有地图的地图,等等,那么你可能会看到一些更漂亮的答案,或者如果地图可以有不同的键,而不仅仅是“测试”,但你只想提取那个等。您可以从迭代中提取函数,使它们模式匹配以接受迭代器,然后模式匹配内容.... blablabla
      • @MicaelNussbaumer 你是对的,这取决于我的预期结果 - 显然,我提供的示例是一个简化,因此这并不能真正帮助澄清“最漂亮”的解决方案是。感谢您对此问题的反馈。
      猜你喜欢
      • 2015-08-10
      • 1970-01-01
      • 2020-11-25
      • 2021-06-13
      • 1970-01-01
      • 2020-04-09
      • 2019-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多