以下代码生成我想要的结果:
// output 1,2,3,4,5,etc
var input$ = Rx.Observable.interval(500).map((v, idx) => idx+1);
var inputEveryOtherOdd$ = input$
// filter even numbers
.filter(v => v % 2)
.map(x => x) // workaround to fix the index (read below)
// filter every other remaining number (take every other odd number)
.filter((v, idx) => {
console.log(`Value: ${v}, Index: ${idx}`)
return !(idx % 2);
})
.subscribe(function(v) {
output.textContent+= v;
})
;
日志产生:
Value: 1, Index: 0
Value: 3, Index: 1
Value: 5, Index: 2
Value: 7, Index: 3
Value: 9, Index: 4
传递第一个过滤器的每个项目都有下一个索引,因此每个项目(0,1,2,3,4,5,etc)
的索引都会加1。
我无法理解的是,如果我删除map
,则第二个过滤器会收到相同项目的不同idx
值:
Value: 1, Index: 0
Value: 3, Index: 2
Value: 5, Index: 4
Value: 7, Index: 6
Value: 9, Index: 8
似乎在第二个过滤器中仍在考虑在第一个过滤器中过滤的值。我无法理解它。过滤函数不会针对值运行,那么对于不存在的项,索引如何递增?为什么map
会有所不同?
我希望将两个过滤器链接在一起会产生与同步过滤相同的结果,并且每个过滤器中的idx
值将为0,1,2,3,4,5,etc
。
var result = [1,2,3,4,5,6,7,8,9]
.filter(v => v % 2)
.filter((v, idx) => !(idx % 2));
我最初使用startWith
代替map
。似乎只是在过滤器之间放置一些内容就会使idx
值成为我所期望的值。
答案 0 :(得分:1)
这个问题具有讽刺意味的是RxJS当前版本(v4)的“特征”。
filter
运算符包含一个优化,以检测它是否以“链式”方式使用,也就是说,如果一行中有多个过滤器。如果是,那么它将不会创建第二个FilterObservable
,而是将新的过滤操作包装为现有Observable的一部分。
因此,无论您将多少个过滤器链接在一起,您始终将为所有过滤器接收相同的索引。
当您在两个过滤器之间使用运算符时,它无法执行优化,因此过滤器将不会合并,您将看到不同的索引。
答案 1 :(得分:0)
索引{{1}}是原始列表中元素的索引,与已过滤的内容无关。