我的" zipLatest"运营商已经存在?

时间:2016-07-04 18:50:28

标签: system.reactive rxjs

关于我为自己写的操作员的快速提问。

请原谅我的穷人的大理石图表:

zip
aa--bb--cc--dd--ee--ff--------gg
--11----22--33--------44--55----
================================
--a1----b2--c3--------d4--e5----

combineLatest
aa--bb--cc--dd--ee--ff--------gg
--11----22--33--------44--55----
================================
--a1b1--c2--d3--e3--f3f4--f5--g5

zipLatest
aa--bb--cc--dd--ee--ff--------gg
--11----22--33--------44--55----
================================
--a1----c2--d3--------f4------g5

zipLatest(我写的那个)几乎与zip同时发生,但没有排队zip包含。

我已经实现了它,我只是想知道这是否已经存在。 我知道我过去曾写过类似的方法,随意发现我在不知情的情况下写了sample运算符。

那么,这是否已经存在于框架中,或者作为一个我无法想到的微不足道的元素组成?

注意:我不想依赖我的输入相等来进行重复数据删除(la distinctUntilChanged)。 它应该使用仅在一个间隔内输出"a"的信号。

2 个答案:

答案 0 :(得分:2)

要更新此问题:RxJS 6中仍然没有针对此要求的运算符,并且似乎没有计划在将来的发行版中使用。也没有建议该运算符的公开拉取请求。

根据建议herecombineLatestfirstrepeat的组合将产生预期的行为:

combineLatest(obs1, obs2).pipe(first()).pipe(repeat());

combineLatest将等待两个可观察物的排放-将所有排放与最新排放分开。 first将在发射后完成Observable,并且repeatcombineLatest上重新订阅,从而使其再次等待两个Observable的最新值。

repeat的重新订阅行为尚未完全记录,但可以在GitHub source中找到:

  

source.subscribe(this._unsubscribeAndRecycle());

答案 1 :(得分:0)

尽管您特别提到不要使用DistinctUntilChanged,但可以将其与计数器一起使用以区分不同的新值:

public static IObservable<(T, TSecond)> ZipLatest<T, TSecond>(this IObservable<T> source, IObservable<TSecond> second)
{
    return source.Select((value, id) => (value, id))
        .CombineLatest(second.Select((value, id) => (value, id)), ValueTuple.Create)
        .DistinctUntilChanged(x => (x.Item1.id, x.Item2.id), new AnyEqualityComparer<int, int>())
        .Select(x => (x.Item1.value, x.Item2.value));
}

public class AnyEqualityComparer<T1, T2> : IEqualityComparer<(T1 a, T2 b)>
{
    public bool Equals((T1 a, T2 b) x, (T1 a, T2 b) y) => Equals(x.a, y.a) || Equals(x.b, y.b);
    public int GetHashCode((T1 a, T2 b) obj) => throw new NotSupportedException();
}

请注意,我在这里使用了Int32-因为这就是Select()给我的-但是对于某些用例来说,它可能很小。 Int64或Guid可能是一个更好的选择。