流 | Stream
Stream
模块,用于创建和组合流。
流是可组合的,懒惰的枚举。任何在枚举过程中逐一生成项目的枚举被称为流。例如,Elixir's Range
是一个流:
iex> range = 1..5
1..5
iex> Enum.map range, &(&1 * 2)
[2, 4, 6, 8, 10]
在上面的示例中,当我们映射到范围上时,枚举期间逐一创建了要枚举的元素。大Stream
模块允许我们在不触发其枚举的情况下映射范围:
iex> range = 1..3
iex> stream = Stream.map(range, &(&1 * 2))
iex> Enum.map(stream, &(&1 + 1))
[3, 5, 7]
注意,我们从一个范围开始,然后我们创建了一个流,用于将范围中的每个项目乘以2.此时,没有计算完成。只有在Enum.map/2
被调用的时候,我们实际上会枚举范围内的每个项目,将它乘以2并加1.我们说函数Stream
是懒惰的
,函数Enum
是渴望的
。
由于他们的懒惰,在与大型(甚至无限)集合一起工作时,流是很有用的。当链接许多操作时Enum
,将创建中间列表,同时Stream
创建稍后执行的计算配方。我们来看另一个例子:
1..3
|> Enum.map(&IO.inspect(&1))
|> Enum.map(&(&1 * 2))
|> Enum.map(&IO.inspect(&1))
1
2
3
2
4
6
#=> [2, 4, 6]
注意,我们首先打印列表中的每个项,然后乘以每个元素2,最后打印每个新值。在本例中,列表被枚举了三次。让我们看一个流示例:
stream = 1..3
|> Stream.map(&IO.inspect(&1))
|> Stream.map(&(&1 * 2))
|> Stream.map(&IO.inspect(&1))
Enum.to_list(stream)
1
2
2
4
3
6
#=> [2, 4, 6]
尽管最终结果是相同的,但是打印项目的顺序却改变了!使用流,我们打印第一个项目,然后打印它的双精度。在这个例子中,列表只被枚举一次!
这就是我们之前所说的流是可组合的、懒惰的可枚举的意思。注意我们可以打电话Stream.map/2
多次,有效地组合流,并使它们懒惰。函数调用函数时,才会执行计算。Enum
模块。
创建流
在Elixir的标准库中有许多返回流的函数,一些示例如下:
IO.stream/2
-流输入行,一个接一个
URI.query_decoder/1
-对查询字符串进行解码,一对一对地对查询字符串进行解码。
此模块还提供了许多创建流的方便函数,如Stream.cycle/1
,,,Stream.unfold/2
,,,Stream.resource/3
还有更多。
注意这个模块中的函数保证返回枚举类型。由于枚举类可以具有不同的形状(结构体,匿名函数等),因此此模块中的函数可能会返回任何形状,并且这可能随时发生变化。例如,今天返回一个匿名函数的函数可能会在将来的版本中返回一个结构体。
摘要
类型
ACC()默认()元件()索引()
功能
chunk_by(枚举,有趣)
分块enum
通过缓冲元素fun
返回相同的值。
chunk_every(enum, count)
捷径chunk_every(enum, count, count)
chunk_every(enum,count,step,leftover \ [])
以块的形式流可枚举的,包含count
项,每个新块开始的位置。step
元素进入可枚举的
chunk_while(enum,acc,chunk_fun,after_fun)
分块enum
当每个块被发出时,使用细粒度控制。
CONCAT(可枚举)
创建一个流,该流枚举可枚举的每个可枚举的
concat(第一,第二)
创建一个流,该流枚举第一个参数,然后是第二个参数。
周期(枚举)
创建一个通过给定可枚举的无限循环的流。
去重复(ENUM)
创建一个流,该流仅在元素与上次发出的元素不同的情况下发出元素。
dedup_by(枚举,有趣)
如果调用fun
元素的结果与调用fun
最后一个发射元素的(存储)结果不同,则创建仅发射元素的流
drop(enum,n)
懒惰地n
从可枚举项中删除下一项
drop_every(枚举,nth)
创建一个流,该流将每一个nth
可枚举项中的
drop_while(枚举,好玩)
延迟删除可枚举元素,而给定函数返回true
每个(枚举,有趣)
为每个项执行给定的函数。
过滤器(枚举,有趣)
创建一个流,该流根据枚举中给定的函数过滤元素。
flat_map(enum, mapper)
映射给定fun
过关enumerable
并使结果变平
interval(n)
创建一个流,该流在给定的句点之后发出一个值。n
以毫秒为单位
(enum,collectable,transform \ fn x - > x end)
将流值作为副作用注入给定的集合中。
迭代(start_value,next_fun)
发出一系列值,从start_value
通过调用next_fun
关于上一值
map(enum, fun)
创建一个流,该流将在枚举时应用给定的函数。
map_every(enum,nth,fun)
创建一个流,该流将对nth
枚举中的每个项目应用给定的函数
reject(enum, fun)
创建一个流,该流将根据枚举中给定的函数拒绝元素。
反复(generator_fun)
返回通过调用generator_fun
反复
资源(start_fun,next_fun,after_fun)
发出给定资源的值序列。
run(stream)
运行给定的流。
scan(enum, fun)
创建一个流,将给定的函数应用于每个元素,发出结果,并使用与下一次计算的累加器相同的结果。使用可枚举中的第一个元素作为起始值。
scan(enum, acc, fun)
创建一个流,将给定的函数应用于每个元素,发出结果,并使用与下一次计算的累加器相同的结果。使用给定的acc
作为起始值
take(enum, count)
从可枚举中获取下一项count
并停止枚举
take_every(enum, nth)
创建一个流,该流接受nth
可枚举项
take_while(enum, fun)
在给定函数返回时,延迟接受可枚举元素。true
timer(n)
创建一个流,该流在n
毫秒
transform(enum, acc, reducer)
转换现有流
transform(enum, start_fun, reducer, after_fun)
转换具有基于函数的开始和完成的现有流。
unfold(next_acc, next_fun)
发出给定累加器的值序列。
uniq(enum)
创建一个流,该流只在元素唯一的情况下发出元素。
uniq_by(enum, fun)
创建一个流,该流仅在元素唯一的情况下发出元素,方法是删除其中的函数元素。fun
返回的重复项目
with_index(枚举,偏移量\ 0)
创建一个流,其中枚举中的每一项将与其索引一起包装在元组中。
zip(enumerables)
将可枚举集合中的相应元素压缩到一个元组流中。
zip(left, right)
将两个藏品拉到一起
类型
acc()
acc() :: any
default()
default() :: any
element()
element() :: any
index()
index() :: non_neg_integer
功能
chunk_by(enum, fun)
chunk_by(Enumerable.t, (element -> any)) :: Enumerable.t
分块enum
通过缓冲元素fun
返回相同的值。
元素只在fun
返回新值或enum
完成了。
实例
iex> stream = Stream.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1))
iex> Enum.to_list(stream)
[[1], [2, 2], [3], [4, 4, 6], [7, 7]]
chunk_every(enum, count)
chunk_every(Enumerable.t, pos_integer) :: Enumerable.t
捷径chunk_every(enum, count, count)
...
chunk_every(enum, count, step, leftover \ [])
chunk_every(Enumerable.t, pos_integer, pos_integer, Enumerable.t | :discard) :: Enumerable.t
以块的形式流可枚举的,包含count
项,每个新块开始的位置。step
元素进入可枚举元素。
step
是可选的,如果未传递,则默认为count
,即各块不重叠。
如果最后一个块没有count
元素来填充块,则元素从leftover
来填补这大块。如果leftover
没有足够的元素填充块,则返回的部分块少于count
元素。
如果:discard
给出leftover
,最后一个块将被丢弃,除非它有确切的count
元素。
实例
iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 2) |> Enum.to_list
[[1, 2], [3, 4], [5, 6]]
iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard) |> Enum.to_list
[[1, 2, 3], [3, 4, 5]]
iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7]) |> Enum.to_list
[[1, 2, 3], [3, 4, 5], [5, 6, 7]]
iex> Stream.chunk_every([1, 2, 3, 4, 5, 6], 3, 3, []) |> Enum.to_list
[[1, 2, 3], [4, 5, 6]]
chunk_while(enum, acc, chunk_fun, after_fun)
chunk_while(Enumerable.t, acc, (element, acc -> {:cont, chunk, acc} | {:cont, acc} | {:halt, acc}), (acc -> {:cont, chunk, acc} | {:cont, acc})) :: Enumerable.t when chunk: any
分块enum
当每个块被发出时,使用细粒度控制。
chunk_fun
接收当前元素和累加器,并且必须返回。{:cont, element, acc}
发出给定块并继续使用累加器或{:cont, acc}
若要不发出任何块并继续返回累加器,请执行以下操作。
after_fun
在完成迭代时调用,并且必须返回。{:cont, element, acc}
或{:cont, acc}
...
实例
iex> chunk_fun = fn i, acc ->
...> if rem(i, 2) == 0 do
...> {:cont, Enum.reverse([i | acc]), []}
...> else
...> {:cont, [i | acc]}
...> end
...> end
iex> after_fun = fn
...> [] -> {:cont, []}
...> acc -> {:cont, Enum.reverse(acc), []}
...> end
iex> stream = Stream.chunk_while(1..10, [], chunk_fun, after_fun)
iex> Enum.to_list(stream)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
concat(enumerables)
concat(Enumerable.t) :: Enumerable.t
创建一个流,该流枚举可枚举的每个可枚举对象。
实例
iex> stream = Stream.concat([1..3, 4..6, 7..9])
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
concat(first, second)
concat(Enumerable.t, Enumerable.t) :: Enumerable.t
创建一个流,该流枚举第一个参数,然后是第二个参数。
实例
iex> stream = Stream.concat(1..3, 4..6)
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5, 6]
iex> stream1 = Stream.cycle([1, 2, 3])
iex> stream2 = Stream.cycle([4, 5, 6])
iex> stream = Stream.concat(stream1, stream2)
iex> Enum.take(stream, 6)
[1, 2, 3, 1, 2, 3]
cycle(enumerable)
cycle(Enumerable.t) :: Enumerable.t
创建一个在给定的可枚举的无限循环中循环的流。
实例
iex> stream = Stream.cycle([1, 2, 3])
iex> Enum.take(stream, 5)
[1, 2, 3, 1, 2]
dedup(enum)
dedup(Enumerable.t) :: Enumerable.t
创建一个流,该流只在元素与上次发出的元素不同的情况下发出元素。
此函数只需要存储最后发出的元素。
元素比较使用===
...
实例
iex> Stream.dedup([1, 2, 3, 3, 2, 1]) |> Enum.to_list
[1, 2, 3, 2, 1]
dedup_by(enum, fun)
dedup_by(Enumerable.t, (element -> term)) :: Enumerable.t
如果调用fun
元素的结果与调用fun
最后一个发射元素的(存储)结果不同,则创建仅发射元素的流。
实例
iex> Stream.dedup_by([{1, :x}, {2, :y}, {2, :z}, {1, :x}], fn {x, _} -> x end) |> Enum.to_list
[{1, :x}, {2, :y}, {1, :x}]
drop(enum, n)
drop(Enumerable.t, non_neg_integer) :: Enumerable.t
下一次可枚举项n
中的项。
如果是阴性n
,它将放弃最后一个n
集合中的项目。请注意,执行此操作的机制将推迟到任何项目的排放。n
枚举发出了其他项。
实例
iex> stream = Stream.drop(1..10, 5)
iex> Enum.to_list(stream)
[6, 7, 8, 9, 10]
iex> stream = Stream.drop(1..10, -5)
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5]
drop_every(enum, nth)
drop_every(Enumerable.t, non_neg_integer) :: Enumerable.t
创建一个流,该流将每一个nth
可枚举项中的项。
第一项总是被删除,除非nth
是0。
nth
必须是非负整数。
实例
iex> stream = Stream.drop_every(1..10, 2)
iex> Enum.to_list(stream)
[2, 4, 6, 8, 10]
iex> stream = Stream.drop_every(1..1000, 1)
iex> Enum.to_list(stream)
[]
iex> stream = Stream.drop_every([1, 2, 3, 4, 5], 0)
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5]
drop_while(enum, fun)
drop_while(Enumerable.t, (element -> as_boolean(term))) :: Enumerable.t
延迟删除可枚举元素,而给定函数返回true
...
实例
iex> stream = Stream.drop_while(1..10, &(&1 <= 5))
iex> Enum.to_list(stream)
[6, 7, 8, 9, 10]
each(enum, fun)
each(Enumerable.t, (element -> term)) :: Enumerable.t
对每个项执行给定的函数。
对于将副作用%28(如打印%29)添加到流中非常有用。
实例
iex> stream = Stream.each([1, 2, 3], fn(x) -> send self(), x end)
iex> Enum.to_list(stream)
iex> receive do: (x when is_integer(x) -> x)
1
iex> receive do: (x when is_integer(x) -> x)
2
iex> receive do: (x when is_integer(x) -> x)
3
filter(enum, fun)
filter(Enumerable.t, (element -> as_boolean(term))) :: Enumerable.t
创建一个流,该流根据枚举中给定的函数过滤元素。
实例
iex> stream = Stream.filter([1, 2, 3], fn(x) -> rem(x, 2) == 0 end)
iex> Enum.to_list(stream)
[2]
平的[医]地图%28 enum,mapper%29
flat_map(Enumerable.t, (element -> Enumerable.t)) :: Enumerable.t
映射给定fun
过关enumerable
并使结果变平。
此函数通过追加调用的结果返回一个新的流。fun
的每一个元素enumerable
在一起。
实例
iex> stream = Stream.flat_map([1, 2, 3], fn(x) -> [x, x * 2] end)
iex> Enum.to_list(stream)
[1, 2, 2, 4, 3, 6]
iex> stream = Stream.flat_map([1, 2, 3], fn(x) -> [[x]] end)
iex> Enum.to_list(stream)
[[1], [2], [3]]
interval(n)
interval(non_neg_integer) :: Enumerable.t
创建一个流,该流在给定的句点之后发出一个值。n
以毫秒为单位。
发出的值是从0
此操作将在每次流新项时按给定间隔阻塞调用方。
不要使用此函数生成数字序列。如果不需要阻塞调用进程,请使用Stream.iterate(0, & &1 + 1)
相反。
实例
iex> Stream.interval(10) |> Enum.take(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
into(enum, collectable, transform \ fn x -> x end)
into(Enumerable.t, Collectable.t, (term -> term)) :: Enumerable.t
将流值注入给定的集合,作为副作用。
此函数常与run/1
因为任何计算都会延迟到流被执行。见run/1
举个例子。
iterate(start_value, next_fun)
iterate(element, (element -> element)) :: Enumerable.t
发出一系列值,从start_value
通过调用next_fun
在以前的值上。
实例
iex> Stream.iterate(0, &(&1+1)) |> Enum.take(5)
[0, 1, 2, 3, 4]
map(enum, fun)
map(Enumerable.t, (element -> any)) :: Enumerable.t
创建一个流,该流将在枚举时应用给定的函数。
实例
iex> stream = Stream.map([1, 2, 3], fn(x) -> x * 2 end)
iex> Enum.to_list(stream)
[2, 4, 6]
9map_every(enum, nth, fun)
map_every(Enumerable.t, non_neg_integer, (element -> any)) :: Enumerable.t
创建一个流,该流将将给定的函数应用于nth
可枚举项中的项。
第一项总是传递给给定的函数。
nth
必须是非负整数。
实例
iex> stream = Stream.map_every(1..10, 2, fn(x) -> x * 2 end)
iex> Enum.to_list(stream)
[2, 2, 6, 4, 10, 6, 14, 8, 18, 10]
iex> stream = Stream.map_every([1, 2, 3, 4, 5], 1, fn(x) -> x * 2 end)
iex> Enum.to_list(stream)
[2, 4, 6, 8, 10]
iex> stream = Stream.map_every(1..5, 0, fn(x) -> x * 2 end)
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5]
reject(enum, fun)
reject(Enumerable.t, (element -> as_boolean(term))) :: Enumerable.t
创建一个流,该流将根据枚举中给定的函数拒绝元素。
实例
iex> stream = Stream.reject([1, 2, 3], fn(x) -> rem(x, 2) == 0 end)
iex> Enum.to_list(stream)
[1, 3]
repeatedly(generator_fun)
repeatedly((() -> element)) :: Enumerable.t
返回通过调用generator_fun
反复。
实例
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exsplus, {1, 2, 3})
iex> Stream.repeatedly(&:rand.uniform/0) |> Enum.take(3)
[0.40502929729990744, 0.45336720247823126, 0.04094511692041057]
resource(start_fun, next_fun, after_fun)
resource((() -> acc), (acc -> {[element], acc} | {:halt, acc}), (acc -> term)) :: Enumerable.t
发出给定资源的值序列。
类似于transform/3
初始累积值,但是在枚举结束时(在成功和失败的情况下)通过start_fun
并且执行一次after_fun
。
通过调用next_fun
前一个累加器生成连续值(初始值是返回的结果start_fun
),并且它必须返回包含要发射的项目列表和下一个累加器的元组。如果枚举返回,则枚举结束{:halt, acc}
。
顾名思义,这个函数对于从资源中流值很有用。
实例
Stream.resource(fn -> File.open!("sample") end,
fn file ->
case IO.read(file, :line) do
data when is_binary(data) -> {[data], file}
_ -> {:halt, file}
end
end,
fn file -> File.close(file) end)
run(stream)
run(Enumerable.t) :: :ok
运行给定的流。
当一个流需要运行时,这是非常有用的,因为它会产生副作用,并且对返回结果没有兴趣。
实例
打开一个文件,替换所有#
通过%
然后流到另一个文件,而不需要在内存中加载整个文件:
stream = File.stream!("code")
|> Stream.map(&String.replace(&1, "#", "%"))
|> Stream.into(File.stream!("new"))
|> Stream.run
在调用Enum函数或Stream.run/1
...
scan(enum, fun)
scan(Enumerable.t, (element, acc -> any)) :: Enumerable.t
创建一个流,将给定的函数应用于每个元素,发出结果,并使用与下一次计算的累加器相同的结果。使用枚举中的第一个元素作为起始值。
实例
iex> stream = Stream.scan(1..5, &(&1 + &2))
iex> Enum.to_list(stream)
[1, 3, 6, 10, 15]
scan(enum, acc, fun)
scan(Enumerable.t, acc, (element, acc -> any)) :: Enumerable.t
创建一个流,将给定的函数应用于每个元素,发出结果,并使用与下一次计算的累加器相同的结果。使用给定的acc
作为起始值。
实例
iex> stream = Stream.scan(1..5, 0, &(&1 + &2))
iex> Enum.to_list(stream)
[1, 3, 6, 10, 15]
take(enum, count)
take(Enumerable.t, integer) :: Enumerable.t
拿走下一个count
可枚举项和停止枚举项。
如果是阴性count
是给出的,最后一个count
价值将被采纳。为此,将充分枚举集合,以保持以下内容2 * count
记忆中的元素。一旦到达集合的结束,最后一个count
元素将被执行。因此,使用否定count
无限的收藏永远不会回来。
实例
iex> stream = Stream.take(1..100, 5)
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5]
iex> stream = Stream.take(1..100, -5)
iex> Enum.to_list(stream)
[96, 97, 98, 99, 100]
iex> stream = Stream.cycle([1, 2, 3]) |> Stream.take(5)
iex> Enum.to_list(stream)
[1, 2, 3, 1, 2]
take_every(enum, nth)
take_every(Enumerable.t, non_neg_integer) :: Enumerable.t
创建一个流,该流接受nth
可枚举项中的项。
第一项总是包括在内,除非nth
是0。
nth
必须是非负整数。
实例
iex> stream = Stream.take_every(1..10, 2)
iex> Enum.to_list(stream)
[1, 3, 5, 7, 9]
iex> stream = Stream.take_every([1, 2, 3, 4, 5], 1)
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5]
iex> stream = Stream.take_every(1..1000, 0)
iex> Enum.to_list(stream)
[]
take_while(enum, fun)
take_while(Enumerable.t, (element -> as_boolean(term))) :: Enumerable.t
在给定函数返回时,延迟接受可枚举元素。true
...
实例
iex> stream = Stream.take_while(1..100, &(&1 <= 5))
iex> Enum.to_list(stream)
[1, 2, 3, 4, 5]
timer(n)
timer(non_neg_integer) :: Enumerable.t
创建一个流,该流在n
毫秒。
发出的值是0
此操作将在给定的时间内阻止调用方,直到该项被流。
实例
iex> Stream.timer(10) |> Enum.to_list
[0]
transform(enum, acc, reducer)
transform(Enumerable.t, acc, fun) :: Enumerable.t when fun: (element, acc -> {Enumerable.t, acc} | {:halt, acc}), acc: any
转换现有流。
它需要一个累加器和一个接收每个流项目和一个累加器的函数,并且必须返回一个包含新流的元组(通常是一个列表),新的累加器或元组:halt
作为第一个元素,而累加器作为第二个元素。
注意:此函数类似于Enum.flat_map_reduce/3
除了后者,后者返回平面列表和累加器,而这个只返回流。
实例
Stream.transform/3
因为它可以用作实现本模块中定义的许多功能的基础,因此非常有用。例如,我们可以实现Stream.take(enum, n)
详情如下:
iex> enum = 1..100
iex> n = 3
iex> stream = Stream.transform(enum, 0, fn i, acc ->
...> if acc < n, do: {[i], acc + 1}, else: {:halt, acc}
...> end)
iex> Enum.to_list(stream)
[1, 2, 3]
transform(enum, start_fun, reducer, after_fun)
transform(Enumerable.t, (() -> acc), fun, (acc -> term)) :: Enumerable.t when fun: (element, acc -> {Enumerable.t, acc} | {:halt, acc}), acc: any
转换具有基于函数的开始和完成的现有流。
只有在转换开始时才计算累加器。它还允许给出After函数,在流停止或完成时调用该函数。
这个函数可以看作是Stream.resource/3
带着Stream.transform/3
...
unfold(next_acc, next_fun)
unfold(acc, (acc -> {element, acc} | nil)) :: Enumerable.t
发出给定累加器的值序列。
通过调用next_fun
对于前一个累加器,它必须返回一个包含当前值和下一个累加器的元组。如果枚举返回,则枚举结束。nil
...
实例
iex> Stream.unfold(5, fn 0 -> nil; n -> {n, n-1} end) |> Enum.to_list()
[5, 4, 3, 2, 1]
uniq(enum)
uniq(Enumerable.t) :: Enumerable.t
创建一个流,该流只在元素唯一的情况下发出元素。
请记住,为了知道一个元素是否唯一,这个函数需要存储该流发出的所有唯一值。因此,如果流是无限的,那么存储的项目数量将会无限增长,永远不会被垃圾收集。
实例
iex> Stream.uniq([1, 2, 3, 3, 2, 1]) |> Enum.to_list
[1, 2, 3]
uniq_by(enum, fun)
uniq_by(Enumerable.t, (element -> term)) :: Enumerable.t
创建一个流,该流仅在元素唯一的情况下发出元素,方法是删除其中的函数元素。fun
返回的重复项目。
功能fun
将每个元素映射到一个用于确定两个元素是否重复的术语。
请记住,为了知道一个元素是否唯一,这个函数需要存储由流发出的所有唯一值。因此,如果流是无限的,则存储的项数将无限增长,永远不会被垃圾收集。
例
iex> Stream.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end) |> Enum.to_list
[{1, :x}, {2, :y}]
iex> Stream.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end) |> Enum.to_list
[a: {:tea, 2}, c: {:coffee, 1}]
with_index(enum, offset \ 0)
with_index(Enumerable.t, integer) :: Enumerable.t
创建一个流,其中枚举中的每个项将与其索引一起包装在元组中。
如果offset
,我们将从给定的偏移量索引,而不是从零索引。
实例
iex> stream = Stream.with_index([1, 2, 3])
iex> Enum.to_list(stream)
[{1, 0}, {2, 1}, {3, 2}]
iex> stream = Stream.with_index([1, 2, 3], 3)
iex> Enum.to_list(stream)
[{1, 3}, {2, 4}, {3, 5}]
zip(enumerables)
zip([Enumerable.t]) :: Enumerable.t
将可枚举集合中的相应元素压缩到一个元组流中。
一旦任何可枚举完成,拉链就会结束。
实例
iex> concat = Stream.concat(1..3, 4..6)
iex> cycle = Stream.cycle(["foo", "bar", "baz"])
iex> Stream.zip([concat, [:a, :b, :c], cycle]) |> Enum.to_list
[{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}]
zip(left, right)
zip(Enumerable.t, Enumerable.t) :: Enumerable.t
把两个收藏品链在一起。
一旦任何可枚举完成,拉链就会结束。
实例
iex> concat = Stream.concat(1..3, 4..6)
iex> cycle = Stream.cycle([:a, :b, :c])
iex> Stream.zip(concat, cycle) |> Enum.to_list
[{1, :a}, {2, :b}, {3, :c}, {4, :a}, {5, :b}, {6, :c}]