【问题标题】:Does my "zipLatest" operator already exist?我的“zipLatest”运算符是否已经存在?
【发布时间】:2016-07-04 18:50:28
【问题描述】:

关于我为自己编写的运算符的快速问题。

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

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 运算符。

那么,这是否已经存在于框架中,或者作为我没有想到的元素的微不足道的组合而存在?

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

【问题讨论】:

  • UniRx 中有一个ZipLatest 的实现 - github.com/neuecc/UniRx
  • 向你保证,我不相信在 Rx 中有这样的实现。顺便说一句,弹珠图很棒。
  • @Enigmativity 嘿,原来如此。乍一看,它甚至似乎在做同样的事情。猜猜我选了一个不错的名字。
  • @psycotica0:这看起来类似于 rxjs 中的withLatestFrom。只是想知道是否应该发出 f5?
  • 看起来类似于 RxJava 的 zipLatest()

标签: system.reactive rxjs


【解决方案1】:

关于这个问题的更新:RxJS 6 中仍然没有包含此要求的操作员,并且似乎没有计划在未来的版本中使用。也没有公开的拉取请求建议使用此运算符。

按照here 的建议,combineLatestfirstrepeat 的组合将产生预期的行为:

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

combineLatest 将等待两个 Observable 的发射 - 丢弃所有发射,除了每个中的最新发射。 first 将在发射后完成 Observable,repeat 重新订阅 combineLatest,导致它再次等待两个 observable 的最新值。

repeat 的重新订阅行为没有完整记录,但可以在GitHub source 中找到:

source.subscribe(this._unsubscribeAndRecycle());

【讨论】:

    【解决方案2】:

    虽然您特别提到不要使用 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 可能是更好的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      相关资源
      最近更新 更多