用于数据流项目的Javascript转换器

用于数据流项目的Javascript转换器,javascript,functional-programming,stream,Javascript,Functional Programming,Stream,在我当前的项目中,我正在处理大量的数值数据流,以及必须以数据流可编程方式在这些数据流上进行的转换 我偶然发现了传感器的想法,它有望解决在大型阵列上处理多个变换的困难。看来传感器并不完全适合我要解决的问题 我正在寻找传感器的模式/概念,它只收集所需的回望量,然后处理结果。类似于浏览器版本的tensorflow、reaktor、max msp(输入输出、流图、基于节点的可视化编程) 这些模块中的大多数都应该连接到源,但也应该能够作为源将这些模块链接到其他模块 source ( a stream )

在我当前的项目中,我正在处理大量的数值数据流,以及必须以数据流可编程方式在这些数据流上进行的转换

我偶然发现了传感器的想法,它有望解决在大型阵列上处理多个变换的困难。看来传感器并不完全适合我要解决的问题

我正在寻找传感器的模式/概念,它只收集所需的回望量,然后处理结果。类似于浏览器版本的tensorflow、reaktor、max msp(输入输出、流图、基于节点的可视化编程)

这些模块中的大多数都应该连接到源,但也应该能够作为源将这些模块链接到其他模块

source ( a stream ) =[new-value]|=> module1 => module2 => ...
                                |=> module3 => module4 // branch off here to a new chain
据我所知,大多数博客中解释的传感器接收整个阵列,并通过选择的变压器为每个单独的值供电

然而,我的模块/变压器不需要太多的数据来工作,比如一个简单的移动平均线示例,回顾4个步骤

我想象这个模块收集足够的数据,直到它开始输出。 我也不需要在内存中保存整个数组,我只需要处理所需的确切数量。结果/输出可选择性地存储在数据库中

stream =[sends-1-value]=> module[collects-values-until-processing-starts] =[sends-one-value]=>...
还可以将多个源连接到一个模块中(传感器似乎没有提供)

这里的传感器模式是否仍然适用,或者是否存在其他情况


老实说,每个程序员都会有一个想法来实现这一点,但我要求一些既定的方法来实现这一点,就像传感器出现一样。

传感器模式当然适用于这里。你可以创建一个浮点处理器,其中传感器与正确的数据结构相匹配。我给你一个简单的例子例如,有一个假设:

  • 您正在使用的流实现
  • 考虑一个简单的队列

    函数SimpleQueue({size}){
    this.size=size
    this.buffer=[]
    }
    SimpleQueue.prototype.push=函数(项){
    this.buffer.push(项目)
    if(this.buffer.length>this.size){
    this.buffer.shift()
    }
    还这个
    }
    SimpleQueue.prototype[Symbol.iterator]=函数*(){
    for(此.buffer的常量项){
    收益项目
    }
    }
    
    我们的简单队列有一个方法
    push
    ,它将一个项目推送到它的内部缓冲区(一个数组)中。简单队列也是可迭代的,因此您可以对(simpleQueue的const x){/*stuff*/}

    现在,我们将在浮点处理器中使用
    SimpleQueue

    const average=iterable=>{
    设总和=0,计数=0
    用于(iterable的常数项){
    总和+=项目
    计数+=1
    }
    返回和/计数
    }
    常量floatingPointAverage=({historySize})=>{
    const queue=new SimpleQueue({size:historySize})
    返回项目=>{
    queue.push(项目)
    平均常数=平均值(队列)
    log(queue,avg)//这显示进程运行时的平均值
    返回平均值
    }
    }
    
    floatingPointAverage
    获取一个项目,将其推入我们的
    SimpleQueue
    ,并返回队列中项目的当前平均值

    最后,我们可以实现和使用我们的传感器

    const{pipe,map,transform}=require('rubico'))
    常数numberstream={
    [Symbol.asyncIterator]:异步函数*(){
    对于(设i=0;i<1000;i++)产生i
    },
    }
    转化(
    烟斗([
    映射(floatingPointAverage({historySize:4})),
    /*这里用浮点平均值进行运算的传感器*/
    ]),
    无效的
    )(数字流)
    

    本例中的传感器是
    map(floatingPointAverage({historySize:4}))
    。此传感器由rubico提供,rubico是我为解决自己的异步问题而编写的库。我在rubico的上下文中编写传感器

    您的输出应该如下所示

    SimpleQueue { size: 4, buffer: [ 0 ] } 0
    SimpleQueue { size: 4, buffer: [ 0, 1 ] } 0.5
    SimpleQueue { size: 4, buffer: [ 0, 1, 2 ] } 1
    SimpleQueue { size: 4, buffer: [ 0, 1, 2, 3 ] } 1.5
    SimpleQueue { size: 4, buffer: [ 1, 2, 3, 4 ] } 2.5
    SimpleQueue { size: 4, buffer: [ 2, 3, 4, 5 ] } 3.5
    SimpleQueue { size: 4, buffer: [ 3, 4, 5, 6 ] } 4.5
    SimpleQueue { size: 4, buffer: [ 4, 5, 6, 7 ] } 5.5
    SimpleQueue { size: 4, buffer: [ 5, 6, 7, 8 ] } 6.5
    SimpleQueue { size: 4, buffer: [ 6, 7, 8, 9 ] } 7.5
    

    传感器只是任意组合变换的组合,具有二进制
    附加
    函数(在半群的意义上)。但您需要将这样的传感器提供给可折叠数据类型的
    折叠
    功能。如果您使用惰性右折叠,则这是streams的一半,这可能是您正在寻找的数据类型。请提供示例输入和预期输出,以便我们更好地理解您的问题。目前的情况是,很难回答您的问题,因为它不客观。您的问题需要更多的关注。流(源)将一次发出一个值,可能是数字或对象,但让我们坚持数字。之后的每个节点都应该能够收集值,直到在该值内进行计算(移动平均线示例),然后输出另一个值。将多个源绑定到一个节点或将多个源输入到一个节点也应该是可能的。简言之,这就像某种连锁反应,最终可以创建这些值的集合,或将其写入数据库。我们不希望将所有记录的值都保存在内存中。