小编War*_*ren的帖子

可见/流向前看

我开始学习Elixir并遇到了一个我无法轻易解决的挑战.

我正在尝试创建一个带有Enumerable.t的函数,并返回另一个包含下n个项的Enumerable.t .它与Enum.chunk(e,n,1,[])的行为略有不同,因为数字迭代计数总是等于原始的可枚举计数.我还需要支持Streams

@spec lookahead(Enumerable.t, non_neg_integer) :: Enumerable.t
Run Code Online (Sandbox Code Playgroud)

使用doctest语法可以很好地说明这一点:

iex> lookahead(1..6, 1) |> Enum.to_list
[[1,2],[2,3],[3,4],[4,5],[5,6],[6]]

iex> lookahead(1..4, 2) |> Enum.to_list
[[1,2,3],[2,3,4],[3,4],[4]]

iex> Stream.cycle(1..4) |> lookahead(2) |> Enum.take(5)
[[1,2,3],[2,3,4],[3,4,1],[4,1,2],[1,2,3]]

iex> {:ok,io} = StringIO.open("abcd")
iex> IO.stream(io,1) |> lookahead(2) |> Enum.to_list
[["a","b","c"],["b","c","d"],["c","d"],["d"]]
Run Code Online (Sandbox Code Playgroud)

我已经研究过实现Enumerable.t协议,但还没有完全理解Enumerable.reduce接口.

有没有简洁/优雅的方式这样做?

我的用例是二进制流上的一个小的固定n值(1或2),因此优化版本的额外点.但是,为了学习Elixir,我对多个用例的解决方案很感兴趣.表现很重要.我将针对解决方案和发布的各种n值运行一些基准测试.

基准更新 - 2015年4月8日

已经发布了6个可行的解决方案.有关基准的详细信息,请访问https://gist.github.com/spitsw/fce5304ec6941578e454.基准测试在列表中运行,其中包含500个不同n值的项目.

对于n = 1,得到以下结果:

PatrickSuspend.lookahead    104.90 µs/op
Warren.lookahead            174.00 µs/op
PatrickChunk.lookahead      310.60 µs/op
PatrickTransform.lookahead  357.00 µs/op
Jose.lookahead              647.60 µs/op
PatrickUnfold.lookahead     1484000.00 µs/op
Run Code Online (Sandbox Code Playgroud)

对于n = 50,结果如下:

PatrickSuspend.lookahead    220.80 µs/op
Warren.lookahead            320.60 µs/op …
Run Code Online (Sandbox Code Playgroud)

elixir

7
推荐指数
1
解决办法
1457
查看次数

标签 统计

elixir ×1