如何解决RxJS范围重叠
How to solve RxJS range overlap?
假设我有两个名为source1
和source2
的可观测序列。我想将source2
与source1
匹配,这样source2
就不会完全重叠source1
:
// source1 = Rx.Observalble.range(...)
// source2 = Rx.Observable.range(...)
|.............| // `source1` range
|--------| // false: `source2` is overlapped
|--------| // false: `source2` is overlapped
|--------| // false: `source2` is overlapped
//|-------| // true: `source2` is not overlapped
// |--------| // true: `source2` is not overlapped
我的解决方案是使用Rx.Observable#first
和Rx.Observable#last
如下:
source1 = Rx.Observable.range(100, 50)
source2 = Rx.Observable.range(150, 10)
pred1 = source1.first().zip(source2.last(), (a, b) => a >= b)
pred2 = source1.last().zip(source2.first(), (a, b) => a <= b)
// Have to use #combineLatest to get it done, don't know why
// #zip doesnt work. Uncomment the line below to check
// pred1.zip(pred2, (a, b) => a || b).subscribe(x => console.log(x))
pred1.combineLatest(pred2, (a, b) => a || b).subscribe(x => console.log(x))
我期待看到使用其他运算符(如#reduce
、#scan
、#flatMap
、#concatMap
或#filter
)的解决方案。
原因是,上面的例子只是比较了两个范围。如果我有一个范围数组需要检查它们是否相互重叠,该怎么办。考虑一个reducer
在这种情况下会有所帮助。
// `array_of_range` could be an array of observable sequences
let source = Rx.Observalbe.fromArray(array_of_range)
source.scan((prev, curr) => {
// Do magic here
}, false)
.subscribe(x => console.log(x)) //=> Check if any two ranges in the `source` are overlapped or not
如果范围重叠,如何将这些范围transform
转换为最佳的较小新范围,使它们不会相互重叠。我知道这不是一个微不足道的答案,所以任何建议都很感激!
更新01:多亏了@joneshf,第一个问题可以通过以下方式解决:
Rx.Observable.merge(
Rx.Observable.range(0, 10),
Rx.Observable.range(11, 20),
Rx.Observable.range(21, 25)
)
.scan(({intersected, set}, n) => ({intersected: set.has(n), set: set.add(n)}),
{intersected: false, set: new Set()}
)
.pluck('intersected')
.reduce((prev, curr) => prev || curr)
.subscribe(x => x ? ‘There was an intersection’ : ‘No intersection’)
欢迎进一步讨论!
您可以按索引分组(使用zip
)
zip(range(1, 10), range(5, 10), range(10, 10)).subscribe(z => {
console.log(z);
});
//=> [ 1 , 5 , 10 ]
//=> [ 2 , 6 , 11 ]
//=> [ 3 , 7 , 12 ]
//=> [ 4 , 8 , 13 ]
//=> [ 5 , 9 , 14 ]
//=> [ 6 , 10, 15 ]
//=> [ 7 , 11, 16 ]
//=> [ 8 , 12, 17 ]
//=> [ 9 , 13, 18 ]
//=> [ 10, 14, 19 ]
然后,您可以重建每个范围,如果且仅当其编号以前从未见过:
输入 | 1st rg | 2nd rg | 3rd rg | 主集|
---|---|---|---|---|
[1,5,10] | [1] | [5] | [10] | 设置{1 5 10} |
[2,6,11] | [1,2] | [5,6] | [10,11] | 设置{1 2 5 6 10 11} |
[3,7,12] | [1,2,3] | [5,6,7] | [10,11,12] | 设置{1 2 3 5 6 7 10 11 12} |
相关文章:
- 正在全局范围中查找JavaScript函数
- 如何通过数组更新角度子范围
- 如何使用ngrepeat和双向绑定获得指令的隔离范围
- HTML范围:动态设置值属性
- "实例范围”;TypeScript类的getter/setter
- jquery日期选择器年份范围默认值
- Jpgraph:如何手动设置X轴和Y轴的范围
- 在对象数组中查找多个值的d3范围
- 动态加载angularjs并生成控制器和范围
- 如何通过谷歌应用程序脚本从谷歌文档中的位置确定命名范围
- 在Materialize Calendar中设置年份范围
- 在MVVM视图模型中处理应用程序范围的元素
- setInterval游戏循环的范围问题
- AngularJS获取范围中的选定项目
- 从指定范围创建字符数组
- ES6是否引入了一种机制来生成块范围的函数语句(而不是表达式)
- Angularjs无法将单选按钮与嵌套范围内的模型绑定
- RxJS的新手,范围不是一个函数
- 如何解决RxJS范围重叠
- RxJS 5可观察和变量范围,也就是为什么我的变量不可读