2015-12-09 28 views
0

我想實現兩個relative complement有限觀察序列,這是我迄今爲止最好的:如何迭代冷可觀察的緩存方式

function relativeComplement (setA, setB, cmp) { 

    return setA.concatMap(objA => 
         setB 
          .reduce((acc, cur) => { 
           if (cmp(objA, cur)) { 
            return {val: objA, skip:true} 
           } 
           return acc 
          }, {val: objA, skip: false}) 
          .filter(obj => !obj.skip) 
          .map(obj => obj.val) 
        ) 
} 

的例子工作,但有兩個問題我一直無法克服。首先,我想使用掃描而不是縮小,因爲我知道如果我已經設置跳過爲真,則繼續序列沒有意義。

第二個問題是最讓我困擾的問題。

如果setB是一個冷觀察值,它將「構造它」,或者做任何可能附加了setA.length次數的副作用。

這是一個jsbin,顯示問題

所以,我有兩個問題。

  • 您是否看到另一種方法來實現克服這兩個問題的相對補充?

  • 我可以緩存setB的結果,因此它不會重播構造和副作用嗎?

注:進出口使用RxJs 5阿爾法,如果你繼續在陣列想法轉換觀測它不具有可觀察原型

+1

對於第一個問題,我可以考慮'expand','takeUntil'和'materialize'的組合,但我想知道它是否真的值得,我的意思是你有大的B組是否有意義的提前退出reduce循環?對於第二個問題,它看起來很難。如果沒有'replay'操作符,則可以編寫自己的。 – user3743222

+0

是的,第一個問題並不是那麼糟糕,實際上,如果這個集合真的很大,那麼整個事情就不得不重新討論,重播就沒有意義了。無論如何,假設我有一個重播,你將如何解決這個問題,弄清楚我不知道B –

+0

的大小我相信RxJS 5它被稱爲'publishReplay' – paulpdaniels

回答

1

重播的方法,並且假設你有一個函數relativeComplementArray

function relativeComplement (setA, setB, cmp) { 
    return Rx.Observable.forkJoin(setA.toArray(), setB.toArray(), function (arrayA, arrayB){ 
    return relativeComplementArray(arrayA, arrayB, cmp); 
    }) 
} 

對於replay功能的版本,這是一個比較複雜一點使用它的功能裏面,因爲你需要的工作不是setB而是setB.shareReplay()

我建議你一個咖喱功能。

function relativeComplement (setB, cmp) { 
    var sharedSetB = setB.shareReplay(); 
    return function (setA) { 
    return Rx.Observable.forkJoin(setA.toArray(), sharedSetB.toArray(), function (arrayA, arrayB) { 
     return relativeComplementArray(arrayA, arrayB, cmp); 
    }) 
    } 
} 

這都是未經測試的,但希望它能讓您朝正確的方向發展。