答案 0 :(得分:2)
将可观察对象作为单个对象(例如,数组)而非作为异步值的序列进行推理是很棘手的。这里发生的是:
您接受obs
观察,然后将count
应用于
count
将等待observable完成并输出一个值,元素数量然后完成。
您过滤了该值,但之后您将toArray
应用于已经完成的obs
。这就是你得到一个空阵列的原因。
所以这里的问题是相同的obs
变量在不同的时间是不同的,所以当你在程序的不同点重用相同的变量时,你不能避免必须推理时间。
现在,如果您想将计数编号输出到subscribe
,您应该可以直接编写obs.count().filter(x => x > 1).toArray()
而不是现在的编号。除了observable之外,flatMap
接受promise和数组作为选择器函数的返回值:
比照https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/selectmany.md
更新: 考虑到这些评论,这就是我提出的(待测试):
var source = Rx.Observable
.from(codes)
.scan(function ( acc, code ) {
acc[code] = acc[code] + 1;
acc.latest = code;
return acc;
}, {})
.filter(function ( acc ) {return acc[acc.latest] > 1;})
.flatMap(function ( acc ) {return acc[acc.latest] == 2? Rx.Observable.repeat(acc.latest, 2) : Rx.just(acc.latest);})
如果您可以等待处理所有值,则可以在过滤器后停止上述操作并添加.last()
。这将为您提供具有所有值计数的最后一个累加器。从那里你可以做你想做的事。
答案 1 :(得分:0)
我找到了类似于user3743222's answer
的解决方案 var filtered = source
.flatMap(obs => {
var accumulated = obs.scan((a,b) => a.concat(b), [])
return obs
.scan((a) => a + 1, 0)
.filter(i => i > 1)
.withLatestFrom(
accumulated,
(a, b) => Rx.Observable.from(b)
)
})
.flatMap(d => d)
.subscribe(d => console.log(d))