Enumerable
Enumerable协议Enum
和Stream
模块使用。
当你在Enum
模块中调用一个函数时,第一个参数通常是一个必须实现这个协议的集合。例如,表达式:
Enum.map([1, 2, 3], &(&1 * 2))
调用Enumerable.reduce/3
通过调用&(&1 * 2)
集合中每个元素的映射函数并使用累积列表消耗该元素来执行构建映射列表的reduce操作。
在内部,Enum.map/2
如下所示:
def map(enum, fun) do
reducer = fn x, acc -> {:cont, [fun.(x) | acc]} end
Enumerable.reduce(enum, {:cont, []}, reducer) |> elem(1) |> :lists.reverse()
end
注意用户提供的函数被封装到一个reducer/0
函数中。该reducer/0
函数必须在每个步骤后返回一个标记元组,如acc/0
类型中所述。
累加器需要标记元组的原因是允许reducer/0
函数将枚举的末尾与底层枚举进行通信,从而允许任何打开的资源正确关闭。它还允许暂停枚举,这在需要许多枚举之间交织时很有用(如zip)。
最后,Enumerable.reduce/3
将返回另一个标记元组,如result/0
类型。
类型
acc()
每个步骤的累加器值。
continuation()
部分应用的约简函数
reducer()
减速器函数
result()
减少操作的结果
t()
功能
count(enumerable)
检索枚举的大小
member?(enumerable, element)
检查元素是否存在于可枚举的
reduce(enumerable, acc, fun)
将可枚举化成元素。
acc()
acc() :: {:cont, term} | {:halt, term} | {:suspend, term}
每个步骤的累加器值。
它必须是带有以下“标记”之一的标记元组:
:cont
-应继续枚举
:halt
-枚举应立即停止
:suspend
-应立即暂停枚举
根据累加器值,由Enumerable.reduce/3
会改变的。请检查一下result/0
键入文档以获取更多信息。
以防万一reducer/0
函数返回:suspend
累加器,它必须由调用方显式处理,并且永不泄漏。
continuation()
continuation() :: (acc -> result)
部分应用的减少功能。
延续是枚举挂起时返回的闭包。调用时,它需要一个新的累加器,并返回结果。
只要以尾递归的方式定义了减值函数,就很容易实现延续。如果函数是尾递归的,则所有状态都作为参数传递,因此,延续将只是部分应用的约简函数。
reducer()
reducer() :: (term, term -> acc)
减速器功能。
应该使用枚举元素和累加器内容调用。
返回下一个枚举步骤的累加器。
result()
result ::
{:done, term} |
{:halted, term} |
{:suspended, term, continuation}
减少手术的结果。
可能是已完成当枚举结束时,或停住/悬吊枚举停止或挂起时,reducer/0
功能。
以防万一reducer/0
函数返回:suspend
累加器:suspended
元组必须由调用方显式处理,并且永不泄漏。在实践中,这意味着常规枚举函数只需要关注:done
和:halted
结果。
此外,:suspend
呼叫必须总是跟着另一个呼叫,最终停止或持续到结束。
t()
t() :: term
count(enumerable)
count(t) :: {:ok, non_neg_integer} | {:error, module}
检索枚举的大小。
它应该返回{:ok, size}
。
如果{:error, __MODULE__}
返回默认算法。reduce
被使用了。该算法在线性时间内运行。
请强制使用默认算法,除非您能够实现一个速度更快的算法。
member?(enumerable, element)
member?(t, term) :: {:ok, boolean} | {:error, module}
检查可枚举元素是否存在。
它应该返回{:ok, boolean}
。
如果{:error, __MODULE__}
返回默认算法。reduce
和匹配%28===
%29操作符被使用。该算法在线性时间内运行。
请强制使用默认算法,除非您能够实现一个速度更快的算法。
reduce(enumerable, acc, fun)
reduce(t, acc, reducer) :: result
将枚举缩小为元素。
的大部分操作Enum
都是以减少的方式实现的。此函数应应用给定的reducer/0
函数对可枚举中的每个项执行,并按返回累加器的预期进行。
例如,下面是reduce
名单:
def reduce(_, {:halt, acc}, _fun), do: {:halted, acc}
def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)}
def reduce([], {:cont, acc}, _fun), do: {:done, acc}
def reduce([h | t], {:cont, acc}, fun), do: reduce(t, fun.(h, acc), fun)
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com