Elixir - Stream 流

许多函数需要一个可枚举的值并返回一个列表。 这意味着,在使用 Enum 执行多个操作时,每个操作都会生成一个中间列表,直到我们得到结果。

Stream (流)支持延迟操作,而不是通过枚举进行急切操作。 简而言之,流是延迟性的、可组合的枚举。 这意味着除非绝对需要,否则 Stream 不会执行操作。 让我们考虑一个例子来理解这一点 −

odd? = &(rem(&1, 2) != 0)
res = 1..100_000 |> Stream.map(&(&1 * 3)) |> Stream.filter(odd?) |> Enum.sum
IO.puts(res)

当上面的程序运行时,会产生以下结果 −

7500000000

在上面给出的示例中,1..100_000 |> Stream.map(&(&1 * 3)) 返回一个数据类型,一个实际流,表示 1..100_000 范围内的映射计算。 它尚未评估这种表示。 流不是生成中间列表,而是构建一系列计算,仅当我们将底层流传递给 Enum 模块时才会调用这些计算。 在处理大型(可能是无限的)集合时,流非常有用。

流和枚举有许多共同的功能。 Streams 主要提供与 Enum 模块相同的功能,该模块在对输入枚举执行计算后生成列表作为其返回值。 其中一些列于下表中 −

序号 功能及其描述
1

chunk(enum, n, step, leftover \\ nil)

以块的形式流式传输可枚举项,每个块包含 n 个项目,其中每个新块开始将元素步进到可枚举项中。

2

concat(enumerables)

创建一个枚举可枚举中每个可枚举的流。

3

each(enum, fun)

为每个项目执行给定的函数。

4

filter(enum, fun)

创建一个流,根据给定的枚举函数过滤元素。

5

map(enum, fun)

创建一个流,该流将在枚举上应用给定的函数。

6

drop(enum, n)

延迟地从可枚举中删除接下来的 n 个项目。