我有一个请求,该请求返回一个对象数组。每个对象都包含一个ID,我可以通过该ID发送另一个请求。基于此结果,我想过滤数组。简化示例:
function getAllObjects(): Observable<{ id: number }[]> {
return of([
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
]);
}
function checkObject(obj): Observable<boolean> {
return of(obj.id % 2 === 0);
}
getAllObjects().pipe(
// TODO
).subscribe(console.log); // I only want to see objects here which passed the async check
答案 0 :(得分:1)
对您有用吗?
getAllObjects().pipe(
flatMap((ar) => ar),
concatMap((obj) => combineLatest([of(obj), checkObject(obj)])),
filter(([_, checkResult]) => checkResult),
map(([obj]) => obj),
toArray(),
).subscribe(console.log);
编辑,我看到您已经找到了解决方案,我的要简单得多,并且我认为您需要一个对象流,而不是将它们作为数组返回。所以我在Edit中添加了toArray。
答案 1 :(得分:0)
可能不是最简单但也可以使用的解决方案
getAllObjects()
.pipe(
switchMap(array =>
combineLatest(array
.map(obj =>
checkObject(obj)
.pipe(
distinctUntilChanged(),
map(boolean => boolean ? obj : null)
)
)
)
),
map(array => array.filter(obj => obj))
)
.subscribe(console.log);
考虑到实时可能的变化
function getAllObjects(): Observable<{ id: number }[]> {
return timer(0, 10000)
.pipe(
map(() => [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
])
);
}
function checkObject(obj): Observable<boolean> {
return timer(1000, 5000)
.pipe(
map(() => obj.id % 2 === 0)
);
}
答案 2 :(得分:0)
const objects$ = getAllObjects().pipe(concatAll());
const objectValidations$ = objects$.pipe(concatMap(checkObject));
zip(objects$, objectValidations$).pipe(
filter(([, validated]) => validated),
map(([obj,]) => obj),
toArray()
).subscribe(console.log);
更新: 我们可以通过并行化“检查”来改善上述解决方案的性能:
getAllObjects().pipe(
concatAll(),
mergeMap(obj =>
checkObject(obj).pipe(
map(isValid => isValid? obj : undefined),
filter(Boolean),
)
),
toArray()
)
那更好,因为如果我们假设以下checkObject
的实现(增加了延迟):
function checkObject(obj) {
return of(obj.id % 2 === 0).pipe(delay(1000));
}
然后,对于n个对象,先前的解决方案将花费n秒,而更新后的解决方案则需要1秒
答案 3 :(得分:-1)
import { map, filter } from 'rxjs/operators';
map(items => items.filter(item => item.id % 2 === 0)),
filter(items => items && items.length > 0)
首先使用map函数并像平常一样过滤数组。 然后,要确保您不会得到null或空数组,请使用filter函数,如果地图为null或空,则该函数不会调用订阅。