获得2个Observable之间的差异,并从结果中创建2个新的observable

时间:2018-04-03 05:12:25

标签: angular rxjs observable

我有2个可观测量:

this.fb.getGroupsAsObservable().subscribe(
  (list: any) => {
    this.allGroups = list;
  }
);

this.fb.getContactsGroups(this.contact).subscribe(
  (list: any) => {
    this.groupsIn = list;
  }
);

这非常有效。但是现在我需要创建一个新的Observable,它与2个可观察对象之间的区别是真实的,我将命名为“groupIn'”。我对rx / js有点新,通常我会使用.has()进行过滤,但这对Observables不起作用。

4 个答案:

答案 0 :(得分:3)

您可以使用forkJoin将它们连接在一起,然后相应地过滤它们。

假设您正在使用es6及以上版本,则数组原型附带includes函数,该函数可以很好地与filter一起使用。

Observable.forkJoin(this.fb.getGroupsAsObservable(), this.fb.getContactsGroups(this.contact))
        .subscribe(([allGroups, groupsIn]) => {
            var difference = allGroups.filter(list => !groupsIn.includes(list));
            console.log(difference)
        })

答案 1 :(得分:1)

你应该有这样的东西:

forkJoin(this.getGroupsAsObservable(), this.getContactsGroups(this.contact))
    .subscribe([list1, list2] => {
        // gets the difference between both returned arrays
        diffList = list1.filter((listItem) => list2.indexOf(listItem) < 0);
    });

这将确保只有当observable都返回值时,您才会执行需要两个observable的返回值的代码

答案 2 :(得分:0)

实际上听起来你正在寻找combineLatest(或者也许zip)而不是forkJoin。当每个源Observable发出至少一个值,然后发出来自任何源Observable的每个发射时,combineLatest会发出。当所有源Observable完成时,forkJoin只会发出一次,这可能无法达到你想要的效果。

const groups$ = this.fb.getGroupsAsObservable();
const contacts$ = this.fb.getContactsGroups(this.contact);

combineLatest(groups$, contacts$, (groups, contacts) => {
  return /* calculate difference */
})

zip运算符也可能是一个选项,但只有当所有源Observable都发出相同数量的项时它才会发出。

答案 3 :(得分:0)

Live working example. 希望这有帮助。正如其他答案所指出的那样,您可以forkJoinzip,但由于它们返回二维数组,因此您可以使用Map operator进行链接。我接近了。

const getGroupsAsObservable$ = of([1, 2, 3, 4, 5]);
const getContactsGroups$ = of([3, 4, 5, 6, 7]);
const symmetricDifference = (arry1, arry2) => (
    arry1.filter(x => !arry2.includes(x))
        .concat(arry2.filter(x => !arry1.includes(x)))
)

const diff = zip(getGroupsAsObservable$, getContactsGroups$)
    .pipe(
        map(joined => {
            const [groups, contacts] = joined;
            return symmetricDifference(groups, contacts);
        })
    );

diff.subscribe(console.log);