Typescript 从合并的流中删除重复项

Typescript 从合并的流中删除重复项,typescript,rxjs,distinct,Typescript,Rxjs,Distinct,我有两个观测值: interface Hour { id:string; } const hours$: Observable<Hour[]> = this.hoursCollection.valueChanges(); const availableHours$: Observable<Hour[]> = this.availableHoursCollection.valueChanges() 假设您使用的是RxJs 4兼容版本 distinct()实际上应该

我有两个观测值:

interface Hour {
   id:string;
}

const hours$: Observable<Hour[]> = this.hoursCollection.valueChanges();
const availableHours$: Observable<Hour[]> = this.availableHoursCollection.valueChanges()

假设您使用的是RxJs 4兼容版本

distinct()
实际上应该可以工作。但是,如果处理的是复杂的事件对象而不是基本体,则应提供键选择器(可能还有比较器):

论据

[keySelector]
函数
):计算每个元素的比较键的函数

[comparer]
函数
):用于比较对象是否相等。如果未提供,则默认为相等比较器函数

示例

在您的情况下,它可以是
.distinct(hours=>hours.id)
(如果
id
是可用于比较对象的键)


我自己从来没有使用过
distinct()
,而是使用了
distinctUntilChanged()
,这不是一回事。

distinct()用于将新发出的值与上次发出的值进行比较。它不会从组合阵列中删除重复项

假设您有一个util函数,可以从名为RemovedUpplicates()的数组中过滤出重复项,您可以在流中这样使用它:

this.events = Observable
    .combineLatest(hours$, availableHours$, 
        (hours, availableHours) => {
            return [...hours, ...availableHours].removeDuplicates();
    })
    .distinct()
    .subscribe((hours) => {
        doSomethingWithUniqueHours(hours);
    });

在这种情况下,您仍然可以使用distinct()过滤出与上次发出的值相同的发出值(小时数组)。

假设您的流发出数组:

import {combineLatest} from 'rxjs/observable/combineLatest';

this.events = combineLatest(hours$, availableHours$, (hours, availableHours) =>{
  return hours.reduce((acc,actual)=>{
    if(!acc.some(hour => hour.id === actual.id)){
       acc = [...acc,actual];
    }
    return acc;
  },[...availableHours]);
});

代码片段没有意义。在一个地方,您引用
hours.id
,在另一个地方,您使用数组排列语法和
hours
。一些数据将使这一点更加清楚。目前,任何回答的人都必须进行一些猜测。请检查我添加的类型是否正确。这里的distinct()是noop,因为总是会发出一个新数组。正如@Igor Soloydenko在他的回答中指出的那样,您只需传入一个选择器和比较器,这样distinct就可以正确地比较数组对象。是否发出“新数组”并不重要。是否相同才是最重要的。感谢这部分工作,如果我删除了availableHours可观察的项目,事件不会更新,我也不太理解代码如果你改变availableHours$发出的列表,但不发出新值,那么事件流将无法更新。
this.events = Observable
    .combineLatest(hours$, availableHours$, 
        (hours, availableHours) => {
            return [...hours, ...availableHours].removeDuplicates();
    })
    .distinct()
    .subscribe((hours) => {
        doSomethingWithUniqueHours(hours);
    });
import {combineLatest} from 'rxjs/observable/combineLatest';

this.events = combineLatest(hours$, availableHours$, (hours, availableHours) =>{
  return hours.reduce((acc,actual)=>{
    if(!acc.some(hour => hour.id === actual.id)){
       acc = [...acc,actual];
    }
    return acc;
  },[...availableHours]);
});