为什么在 Elixir Works 中模式匹配 Map 与 Stream/Enum 模块中的 Tuple?
Why does pattern matching Map with Tuple inside Stream/Enum module in Elixir Works?
如果我没理解错的话,elixir 中的 tuples 表示为 {}
而 Maps 表示为 key:value 与 %{key: value}
.
配对
在下面的代码中,Stream.filter
和 Enum.map
接受 entries
作为输入,这是一个 Map
并对其进行迭代。
但是它们内部的 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
Elixir 中的迭代可以通过 Enumerable
协议的实现来实现。这意味着,任何实现 Enumerable
的东西都可以使用 Enum
和 String
模块中的方法进行迭代。
本协议的实现forMap
delegates to Enumerable.List.reduce/3
, passing the map converted to a list with :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
在您的示例中,这些元组正在 Enum.map
中发出。
如果我没理解错的话,elixir 中的 tuples 表示为 {}
而 Maps 表示为 key:value 与 %{key: value}
.
在下面的代码中,Stream.filter
和 Enum.map
接受 entries
作为输入,这是一个 Map
并对其进行迭代。
但是它们内部的 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
Elixir 中的迭代可以通过 Enumerable
协议的实现来实现。这意味着,任何实现 Enumerable
的东西都可以使用 Enum
和 String
模块中的方法进行迭代。
本协议的实现forMap
delegates to Enumerable.List.reduce/3
, passing the map converted to a list with :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
在您的示例中,这些元组正在 Enum.map
中发出。