Javascript流库-实现

时间:2019-03-07 09:26:02

标签: javascript functional-programming

java流(或其他语言的任何其他功能库)非常好。

例如,您可以拥有(js sudo code)。

Stream.of([1, 2, 3]).filter(x => x > 2).map(x => x * 5).result(); // [15]

忽略语法或特定实现,这只是一个示例。

现在我的问题是流程有点复杂。

例如,如果我在每个步骤中都需要这样的不同数据:

Stream.of([1,2, 3])
  .map(x => x * 3)
  .zip([4, 5, 6])
  .map(..//here i need the initial array)
  .map(..//here i need the zipped array)
  .total(..//

如您所见,在某些方法中,我需要最后一个计算值,在某些方法中,我需要初始值。

此外,在某些情况下,我需要中间值,但在计算中间值之后。

map(x => x * 1).map(x => x * 2).map(x => x * 4).map(..//i need the result from 2nd map (x*2)

这是一个愚蠢的例子,但说明了问题所在。

这个问题有很好的解决方法。

我以为我可以将所有数据保存在对象中,但这会导致更冗长的代码,因为在每一步中,我都必须设置并从对象中获取属性。

另一个例子: 对数字求和:[1, 2, 3, 4] -> 10 过滤大于2的数字:{{1} 将每个数字乘以总和:[1, 2, 3, 4] -> [3, 4]

[30, 40]

谢谢

2 个答案:

答案 0 :(得分:2)

如果需要中间结果,请保存计算:

const initial = Stream.of([1,2,3,4]);
const total   = initial.sum();
const result  = initial.filter(x => x > 2).map(x => x * total);

以上示例是编写此类代码的最合逻辑的方法。我不明白为什么您要编写如下代码:

Stream.of([1,2,3, 4])
    .sum()
    .filter(/* here will be the sum, but i want the initial array and later the sum */)
    .map(/* here i want the filtered array and the calculated sum */)

您的例子令人困惑和误导。以功能样式编写的代码无需链接。

答案 1 :(得分:1)

我并不了解所有的语言-我主要是Java开发人员-但据我所知,不,没有像您搜索的语言那样的灵丹妙药。

在这些类型的库中使用的 Stream 的隐喻总是像这样

[input stream] --{read elements one by one}--> [calculate] --> [output stream]

不要将[input stream]视为集合的视图(尽管在99%的情况下,它是这样使用的)。更一般地将其视为例如网络套接字,您可以从中一个一个地读取元素。并且,当您阅读完一个元素后,该元素就从网络套接字中消失了,您将无法倒带。

所以,基本原理是

  • 每个元素仅被读取一次,
  • 所有[calculate]进程都可以并行运行,并且
  • [calculate]进程没有副作用

此原理允许库在内部优化和并行化计算,这是Stream API的主要目标。

因此,要回答您的问题:如果需要一个需要多次访问流元素的计算,则需要将原始流或中间结果保存在集合中。

相关问题