如果 x 毫秒前发生相同的发射,则阻止发射

Prevent emission if the same emission occurred x milliseconds ago

当且仅当在最后 x 毫秒内发射了完全相同的项目时,我想防止发射发生。我查看了油门和去抖运算符,但我不确定它们是否可以帮助我。有没有我可以使用的其他运算符,或者我可以以某种方式组合它们?

您可以为每个项目添加时间戳和配对,然后检查时间和相等性的边界条件。

   randomSource
                .timestamp()
                .pairwise()
                .where(pair => pair[0].timestamp - pair[1].timestamp < limit && pair[0].value === pair[1].value);

然后应用 .select(pair => pair[0].value) 取回您的原始物品。

C# 中的工作示例,源代码在随机时间内生成间隔为 1 到 5 的随机项:

    static IObservable<T[]> Pairwise<T>(this IObservable<T> source)
    {
        source = source.Publish().RefCount();
        return source.Skip(1).Zip(source, (a, b) => new[] { a, b });
    }

    static void Main(string[] args)
    {

        var randomSource =
            Observable.Defer(() => Observable.Timer(TimeSpan.FromSeconds(new Random().NextDouble() * 2))).Repeat().Publish().RefCount().Select(_ => new Random().Next(1, 5));

        var limit = TimeSpan.FromSeconds(1);

        var sameDebounce =
        randomSource
            .Timestamp()
            .Pairwise()
            .Where(pair => pair[0].Timestamp - pair[1].Timestamp < limit && pair[0].Value == pair[1].Value);


        sameDebounce.Subscribe(c => Console.WriteLine("{0} {1}", c[0], c[1]));
        Console.ReadLine();

    }

输出:

2@9/7/2017 5:00:04 AM +00:00 2@9/7/2017 5:00:04 AM +00:00
2@9/7/2017 5:00:09 AM +00:00 2@9/7/2017 5:00:08 AM +00:00
1@9/7/2017 5:00:23 AM +00:00 1@9/7/2017 5:00:23 AM +00:00
2@9/7/2017 5:00:33 AM +00:00 2@9/7/2017 5:00:32 AM +00:00

因为你的问题没有完全解释这种情况,比如将下一个发射值与上一个发射值或任何上一个发射值或其他东西进行比较。 我会采用一般方法来找到解决方案。

示例在 RxJava.

您可以将 timestamp()filter() 运算符一起使用,如下所示:

ArrayList<String> list = new ArrayList<>();
        final long[] timeOfSubscribe = {-1};
        final long timeDuration = 2 * 1000; // 2 seconds
        Observable.fromIterable(list)
                .timestamp()
                .filter(item -> item.time() > (timeDuration + timeOfSubscribe[0]) && item.value().equals("your last value"))
                .doOnSubscribe(__ -> timeOfSubscribe[0] = Calendar.getInstance().getTimeInMillis())
                .subscribe();

我想这个片段可以帮助您只需要更改 filter() 运算符中的发射值比较登录。如果您正在寻找最后发出的值,您可以使用 doOnNext() 运算符停止最后发出的值(有简单的情况),或者如果您正在寻找所有最后发出的值,您需要将发出的值存储在列表中并检查。

希望对您有所帮助。

您可以使用 groupByUntil 执行此操作,以基本上消除单个项目

o
  .groupByUntil(x => x, x => x, x => Observable.timer(1000))
  .flatMap(grp => grp.first())