我想实现两个有限Observable序列的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)
)
}
这个例子有效但有两个我无法克服的问题。首先,我想使用scan而不是reduce,因为我知道如果我已经将skip设置为true,那么继续序列是没有意义的。
第二个问题是让我最困扰的问题。
如果setB是一个冷可观察对象,它将“构造它”,或者它可能附加了setA.length次数的任何副作用。
这是显示问题的jsbin
所以我有两个问题。
您是否看到另一种方法来实现克服这两个问题的相对补充?
我可以缓存setB的结果,这样它就不会重播构造和副作用吗?
注意:我使用RxJs 5 alpha并且在可观察原型中没有重放方法
答案 0 :(得分:1)
如果继续转换数组构思中的observable,并假设你有一个函数select C.name, P.title, P.year, qnty, price, lowest
from yrb_customer C, yrb_purchase P,
(
select distinct M.cid, O.title, O.year, min(price)
from yrb_member M, yrb_purchase P, yrb_offer O
where M.club = O.club and
M.cid = P.cid and
P.title = O.title and P.year = O.year
group by M.cid, O.title, O.year
) B,
yrb_offer O
where P.cid = B.cid and P.title = B.title and
P.year = B.year and P.title = O.title and
P.year = O.year and P.club = O.club and
C.cid = P.cid and
O.price > B.lowest
order by C.name, P.title, P.year;
:
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()
这都是未经测试的,但希望它能让你朝着正确的方向前进。