Rxjs 如何根据每个值的可观察属性筛选出可观察值

Rxjs 如何根据每个值的可观察属性筛选出可观察值,rxjs,Rxjs,假设我有一个可观察的项目 let items$ = Observable<Item[]> 接收当前选定的所有项目列表的最佳方式是什么?我的解决方案看起来不太正确: items$.pipe( switchMap(items => combineLatest(items.map(item => item.isSelected$.pipe( map(isSelected =>

假设我有一个可观察的项目

let items$ = Observable<Item[]>
接收当前选定的所有项目列表的最佳方式是什么?我的解决方案看起来不太正确:

items$.pipe(
    switchMap(items =>
        combineLatest(items.map(item =>
                item.isSelected$.pipe(
                    map(isSelected => ({item: item, isSelected: isSelected})))),
            map(items => items.filter(item => item.isSelected).map(item => item.item))
        )))
它是有效的,我以前也用过它,但对于我经常要做的事情来说,它是如此复杂的构造。一定有更好的办法

注意:订阅者需要所有选定项目的列表,而不是单个项目的流

示例:
项目$
将发出以下列表:

[{id: 1, isSelected$: of(true)}, 
    {id: 2, isSelected$: of(false)}, 
    {id:3, isSelected$: of(true)}]
作为订阅的结果,我们希望获得以下列表:

[{id: 1}, {id: 3}]

你可能想试试这样的东西

.pipe(
    switchMap(
        items => from(items).pipe(
            mergeMap(item => item.isSelected$.pipe(map(sel => ({sel, item})))),
            filter(data => data.sel),
            map(data => ({id: data.item.id})),
            toArray()
        )
    ),
)
首先,我们获取
items$
的通知,这是一个数组,并将其转换为一个可观察的对象,该对象同时发出一个项目

然后,键位于作为参数传递给
mergeMap
的函数中

item.isSelected
返回要用于筛选的
可观察项。我们通过
map
应用一个变换,将其转化为一个对象,该对象包含两个属性:选择标准和整个项目

其余的只是根据选择标准进行过滤,然后再次转换以返回

我已经用以下测试数据测试了上述代码

const items$ = of(
    [
        {id: 1, isSelected$: of(true)},
        {id: 2, isSelected$: of(false)},
        {id: 3, isSelected$: of(true)},
        {id: 4, isSelected$: of(true)},
    ],
    [
        {id: 10, isSelected$: of(true)},
        {id: 20, isSelected$: of(true)},
        {id: 30, isSelected$: of(false)},
        {id: 40, isSelected$: of(false)},
    ]
);

这肯定比我的方法好。但是,最后如何收集所有项目作为列表?我可能忘了明确提到,结果必须是一个项目列表。可能
toArray
操作符就是您正在寻找的,它似乎是
toArray
在源可观测完成时发出的。但是我想,
items$
永远不会完成,那么我们得到数组了吗?是的,你是对的,它会在源可观测完成时发出。如果你想在最后列出一个清单,这是非常合乎逻辑的。你能详细说明一下你想要什么样的名单吗?如果
items$
从未完成,该列表会是什么样子?
items$
是一个长期存在的可观察对象,它会发出项目列表。请参见编辑。
const items$ = of(
    [
        {id: 1, isSelected$: of(true)},
        {id: 2, isSelected$: of(false)},
        {id: 3, isSelected$: of(true)},
        {id: 4, isSelected$: of(true)},
    ],
    [
        {id: 10, isSelected$: of(true)},
        {id: 20, isSelected$: of(true)},
        {id: 30, isSelected$: of(false)},
        {id: 40, isSelected$: of(false)},
    ]
);