是否可以在 Elixir 中的流上运行reduce?

bez*_*oon 4 elixir

是否可以减少 Elixir 中的流?

我看到 Stream.scan 但它不返回累加器。

file_stream
|> Stream.each(&parse_line/1)
|> Enum.reduce(&reduce_fn/2)
Run Code Online (Sandbox Code Playgroud)

我似乎遇到了以下问题,但想知道是否可以这样做?

Ale*_*kin 7

减少流是没有意义的。Enum模块中的函数与模块中的函数之间的核心区别Stream是,前者是贪婪的,而后者是懒惰的。

\n

也就是说,Stream生成一组转换,可以在每个集合\xe2\x80\x99s 元素基础上延迟应用,传递。

\n

但是reduce(又名foldl)已经是一种有效的贪婪操作,如果不遍历整个集合就无法得到结果。(因此Stream.scan/3顺便说一句,这就是为什么不返回累积值的原因。)

\n
\n

枚举

\n
#  ===== code =====        ===== piped through =====\n[1, 2, 3]                        # [1, 2, 3]\n#                                #     \xe2\x87\x93\n|> Enum.map(&IO.inspect/1)       # [1, 2, 3]\n#                                #     \xe2\x87\x93\n|> Enum.map(&IO.inspect/1)       # [1, 2, 3]\n\n#\xe2\x87\x92 1 2 3 1 2 3\n
Run Code Online (Sandbox Code Playgroud)\n

溪流

\n
#  ===== code =====        ===== piped through =====\n[1, 2, 3]                        # 1  2  3\n#                                # \xe2\x87\x93  \xe2\x87\x93  \xe2\x87\x93\n|> Stream.map(&IO.inspect/1)     # 1  2  3\n#                                # \xe2\x87\x93  \xe2\x87\x93  \xe2\x87\x93\n|> Stream.map(&IO.inspect/1)     # 1  2  3\n|> Enum.to_list()                # termination!\n#                                # \xe2\x87\x92  \xe2\x87\x92  \xe2\x87\x92\n\n#\xe2\x87\x92\xc2\xa01 1 2 2 3 3\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我不确定我是否遵循。跟踪累加器_已经_意味着无法将“reduce”嵌入到“Stream”链中。延迟处理意味着输入的第一个元素“经历所有转换”,然后是第二个元素,依此类推。如果中间的元素经历所有元素,这是不可能的。此步骤将终止“Stream”。我将在答案中添加“图片”。 (4认同)
  • 添加。当有一个巨大的列表时,急切操作将在每个步骤上产生一个中间结果(在例如“map”的情况下是另一个巨大的列表),并且它可能非常消耗内存。`Stream` 延迟地将其逐个元素传递到 _transformations_ ,根本不产生任何中间结果。 (4认同)