RxJs: lossy form of zip operator

后端 未结 5 1699
一整个雨季
一整个雨季 2021-01-02 14:40

Consider using the zip operator to zip together two infinite Observables, one of which emits items twice as frequently as the other.
The current implementation is loss-l

5条回答
  •  隐瞒了意图╮
    2021-01-02 15:30

    This gives the sequence [ 0, 2 ] [ 1, 5 ] [ 2, 8 ] [ 3, 12 ] ...

    const interval1 = Rx.Observable.interval(1000)
    const interval2 = Rx.Observable.interval(300)
    
    const combined = Rx.Observable.combineLatest(interval1, interval2);
    const fresh = combined.scan((acc, x) => { 
        return x[0] === acc[0] || x[1] === acc[1] ? acc : x 
      })
      .distinctUntilChanged() //fresh ones only
    
    fresh.subscribe(console.log);
    

    with arguably fewer operators. Not sure how efficient it is though.
    CodePen

    For update #3,

    Then you'd need a key for each source item.

    // Simulated sources according to latest spec provided (update #3)
    const source1 = Rx.Observable.from(['x','y','z'])
    const source2 = Rx.Observable.from(['a','a','b','b','c'])
    
    // Create keys for sources
    let key1 = 0
    let key2 = 0
    const keyed1 = source1.map(x => [x, key1++])
    const keyed2 = source2.map(x => [x, key2++])
    
    const combined = Rx.Observable
      .combineLatest(keyed1, keyed2)
      .map(([keyed1, keyed2]) => [...keyed1, ...keyed2]) // to simplify scan below
    combined.subscribe(console.log) // not the output, for illustration only
    console.log('-------------------------------------')
    
    const fresh = combined.scan((acc, x) => { 
        return x[1] === acc[1] || x[3] === acc[3] ? acc : x 
      })
      .distinctUntilChanged() //fresh ones only
    
    const dekeyed = fresh
      .map(keyed => { return [keyed[0], keyed[2]] })
    dekeyed.subscribe(console.log); // required output
    

    This produces

    ["x", "a"]  
    ["y", "a"]  
    ["z", "b"]  
    

    CodePen (refresh CodePen page after opening console, for better display)

提交回复
热议问题