为什么在 Elixir Works 中的 Stream/Enum 模块中模式匹配 Map 与 Tuple?

Pra*_*ere 1 elixir

如果我理解正确的话,elixir 中的元组用 表示,{}Maps表示为键:值对,%{key: value}.

在以下代码中,Stream.filterandEnum.map接受entries作为输入,即 aMap并对其进行迭代。

但是lambda它们内部的函数正在做一个模式匹配,{_, entry}它是一个tuple. 这是怎么回事?

defmodule TodoList do
   defstruct auto_id: 1, entries: %{}

   def new(), do: %TodoList{}

  def add_entry(todo_list, entry) do
    entry = Map.put(entry, :id, todo_list.auto_id)
    new_entries = Map.put(
      todo_list.entries,
      todo_list.auto_id,
      entry)

    %TodoList{todo_list |
      entries: new_entries,
      auto_id: todo_list.auto_id + 1
    }
  end

  def entries(todo_list, date) do
    todo_list.entries
    |> Stream.filter(fn {_, entry} -> entry.date == date end)
    |> Enum.map(fn {_, entry} -> entry end)
  end
end
Run Code Online (Sandbox Code Playgroud)

Ale*_*kin 8

Elixir中的迭代可以通过Enumerable协议的实现来实现。这意味着,任何实现Enumerable都可以使用来自EnumString模块的方法进行迭代。

此协议的实现 Map 委托Enumerable.List.reduce/3,传递映射转换为列表:maps.to_list/1

后者将地图转换为表单中的列表[{k1, v1}, {k2, v2}, ...]

iex|1 ? :maps.to_list(%{k1: :v1, k2: :v2})
#? [k1: :v1, k2: :v2] # essentially the list of tuples
iex|2 ? [k1: :v1, k2: :v2] == [{:k1, :v1}, {:k2, :v2}]
#? true
Run Code Online (Sandbox Code Playgroud)

这些元组正在Enum.map您的示例中发出。

  • 欢迎。[这里是开始阅读协议的最佳位置](https://elixir-lang.org/getting-started/protocols.html)。 (2认同)