从合并流中删除重复项

时间:2018-01-03 01:51:03

标签: typescript rxjs distinct

我有两个可观察者:

interface Hour {
   id:string;
}

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

我正在将这两个观察结合起来 我有一些重复的项目,其ID与值相同 如果hours.id === availableHours.id则应过滤掉小时内的对象

我尝试了不同但我没有得到你比较值的部分

this.events = Observable.combineLatest(hours$, availableHours$, (hours, availableHours) => [...hours, ...availableHours]).distinct()

3 个答案:

答案 0 :(得分:2)

假设您的流发出数组

function invert(object) {
    var result = {};

    function setValue(target, path, value) {
        var last = path.pop();
        path.reduce((o, k) => o[k] = o[k] || {}, target)[last] = value;
    }

    function iter(o, p) {
        if (o && typeof o === 'object') {
            Object.keys(o).forEach(k => iter(o[k], [...p, k]));
            return;
        }
        p.unshift(p.pop());
        setValue(result, p, o);
    }

    iter(object, []);
    return result;
}

var source = { cookie: { CookieMessage: { DE: "Nachricht", EN: "Message" } } },
    target = invert(source);

console.log(target);

答案 1 :(得分:0)

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

实际上,

distinct()应该可行。但是,如果您正在处理复杂的事件对象而不是基元,那么您应该提供一个键选择器(也许是一个比较器):

  

参数

     

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

     

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

     

Source: RxJs extensions

示例

/* With key selector */
var source = Rx.Observable
  .of({value: 42}, {value: 24}, {value: 42}, {value: 24})
  .distinct(function (x) { return x.value; });

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

我自己从未使用distinct(),而是distinctUntilChanged()这不是同一件事。

答案 2 :(得分:0)

distinct()用于将新发射值与最后发射值进行比较。它不会从组合数组中删除重复项。

所以,让我们假设你有一个util函数可以过滤掉一个名为removeDuplicates()的数组中的重复项,你可以在你的流中使用它:

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

在这种情况下,您仍然可以使用distinct()过滤掉与发出的最后一个相同的发射值(小时数组)。