我有两个可观察者:
我想使用第一个值中的值来过滤第二个observable。
从服务器接收的值包括tag
属性,该属性对应于复选框列表中的值。上述两者的组合产生的可观察性只会产生服务器的值,其tag
属性包含在勾选复选框中。
答案 0 :(得分:31)
您可以使用withLatestFrom
。
source.withLatestFrom(checkboxes, (data, checkbox) => ({data, checkbox}))
.filter(({data, checkbox}) => ...)
此处,checkboxes
是一个表示复选框输入列表的observable。 source
是一个可观察的,表示来自服务器的事件流。在过滤功能中,您可以检查数据是否与复选框设置相比有效,并让它通过。
请注意,在流可以发出任何内容之前,checkboxes
至少会发出至少1个值。
聚苯乙烯。关于其他答案,即使源为cold,此解决方案仍然有效。
答案 1 :(得分:6)
为了使用流B的值过滤流A,您需要观察流B并使用最新值来过滤流A.
使用switch()
将B observable转换为A observable的可观察产生值。
checkedInputValuesSource
.map(function (options) {
return dataSource
.filter(function (value) {
return options.indexOf(value) !== -1;
});
})
.switch()
.subscribe(function (x) {
console.log('out: ' + x);
});
使用switch()
假设dataSource
是hot observable。
使用interval()
生成虚拟数据的示例:
var input,
checkedInputValuesSource,
dataSource;
input = document.querySelectorAll('input');
// Generate source describing the current filter.
checkedInputValuesSource = Rx.Observable
.fromEvent(input, 'change')
.map(function () {
var inputs = document.querySelectorAll('input'),
checkedInputValues = [];
[].forEach.call(inputs, function (e) {
if (e.checked) {
checkedInputValues.push(e.value);
}
});
return checkedInputValues;
})
.startWith([]);
// Generate random data source (hot).
dataSource = Rx.Observable
.interval(500)
.map(function () {
var options = ['a', 'b', 'c'];
return options[Math.floor(Math.floor(Math.random() * options.length))];
})
.do(function (x) {
console.log('in: ' + x);
})
.share();
checkedInputValuesSource
.map(function (options) {
return dataSource
.filter(function (value) {
return options.indexOf(value) !== -1;
});
})
.switch()
.subscribe(function (x) {
console.log('out: ' + x);
});

<script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script>
<input type='checkbox' value='a'>
<input type='checkbox' value='b'>
<input type='checkbox' value='c'>
&#13;
此示例将生成类似于:
的输出in: c
in: a
out: a
in: b
in: c
out: a
in: b
in: a
in
反映所有生成的输入,b
反映通过过滤器的数据。通过选中反映值&#34; a&#34;,&#34; b&#34;的复选框输入来调整过滤器。和&#34; c&#34;。
答案 2 :(得分:2)
显然,我需要的是select
,filter
和switchLatest
的组合。我写了一个小的测试用例来证明这一点:https://gist.github.com/igstan/d5b8db7b43f49dd87382#file-observable-filter-observable-js-L36-L45
答案 3 :(得分:0)
扩展@Dorus 的回答...在 Kotlin 中,您可以这样做:
val observable: Observable<Data> = ...
val filter: Observable<Checkbox> = ...
val filtered: Observable<Data> =
observable.filterWithLatestFrom(filter) { checkbox -> checkbox.isSelected }
使用扩展功能:
/**
* Return an [Observable] with type [T1] that is filtered using the last event emitted by the [other] observable.
*/
fun <T1 : Any, T2 : Any> Observable<T1>.filterWithLatestFrom(other: Observable<T2>, filterFunction: (T2) -> Boolean)
: Observable<T1> {
return this.withLatestFrom(other) { obs1, obs2 -> Pair(obs1, obs2) }
.filter { (_, obs2) -> filterFunction.invoke(obs2) }
.map { (obs1, _) -> obs1}
}