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]);
});