首页 > 解决方案 > RxJs 独特地合并两个可观察对象

问题描述

我正在使用 rxjs 在 Angular 应用程序中构建搜索和过滤系统。

我有以下内容:

interface User{ //exmaple model
 _id: string;
 name: string;
}

filters$ = new BehaviorSubject<Array<User>>([]);
search$ = new BehaviorSubject<Array<User>>([]);

// I use these two and merge them in another function as following

const myData$ = merge(this.search$.asObservable(), this.filters$.asObservable())
.pipe(distinctUntilChanged(distinctCheck))

效用函数distinctCheck类似于:

const distinctKey = (elem) => {
    if(elem === null){
      return elem
    }
    if(this.hasId(elem)){
      return elem["_id"];
    }
    if(this.hasName(elem)){
      return elem["name"]
    }
    return this.createComparisonString(elem)
  }

但这让我觉得其中一个或另一个可观察到的。所以我的问题是:

如何合并两个 observables 并只发出两个数组共有的值?有时 filters$ 可能会发出一个包含 30 个元素的数组。有时 search$ 可能会发出一个只有 2 个元素的数组?

IE:

如果filter$包含:

[{_id:'1', name:'jhon'},{_id:'2', name:'doe'},{_id:'3', name:'jolly'},{_id:'4', name:'some random dude'},{_id:'5', name:'some random other dude'},{_id:'6', name:'johny'},{_id:'7', name:'bravo'}]

search$包含:

[{_id:'1', name:'jhon'},{_id:'101', name:'myDoe'},{_id:'301', name:'some-jolly'},{_id:'4', name:'some random dude'}, {_id:'7', name:'bravo'}]

我想myData$发出类似的东西:

[{_id:'1', name:'jhon'},{_id:'4', name:'some random dude'}, {_id:'7', name:'bravo'}]

谢谢你们!:)

标签: angulartypescriptrxjsrxjs6

解决方案


运算符的compare功能distinctUntilChanged用于判断先前的发射是否与当前的发射不同。

据我了解您的问题,您正在寻找searchfilter数组之间的交集。

首先,使用操作符在发射combineLatest时得到通知。 然后,您可以使用 lodash 之类的方法来获取数组交集。search$filter$
intersectionWith

您的代码应如下所示:

const comperator = (search, filter) => filter._id === search._id && filter.name === search.name; 

const myData$ = combineLatest(search$, filter$).pipe(
  map(([search, filter]) => intersectionWith(search, filter, comperator))
);

您可以在此 stackblitz中查看完整的运行代码


推荐阅读