2017-09-06 10 views
10

同じ正確なアイテムが最後のxミリ秒以内に放出された場合にのみ発光が発生しないようにしたいと思います。私はスロットルとデバウンスのオペレータを見てきましたが、私がここで私を助けることができるかどうかはわかりません。私が使用できる別の演算子がありますか、何とかそれらを合成できますか?同じ発光がミリ秒前に発生した場合の発光の防止

+0

をデバウンスするgroupByUntilでこれを行うことができ、あなたはより多くの情報を提供することはできますか?たとえば、どのオブジェクトを使用しているか、アイテムの排出速度はどれくらいですか?あなたはどこからそれらのアイテムを放出しますか?それらのアイテムが1つずつ放出されるか、バッチで放出されることが重要ですか? –

答えて

1

各項目のタイムスタンプとペアリングを行い、時間と平等の境界条件を確認できます。

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

次に、.select(pair => pair[0].value)を適用して元の商品を戻してください。ランダムな時間にわたり間隔1と5の間のランダムなアイテムを生成したソースで、C#での例作業

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(); 

    } 

出力:

[email protected]/7/2017 5:00:04 AM +00:00 [email protected]/7/2017 5:00:04 AM +00:00 
[email protected]/7/2017 5:00:09 AM +00:00 [email protected]/7/2017 5:00:08 AM +00:00 
[email protected]/7/2017 5:00:23 AM +00:00 [email protected]/7/2017 5:00:23 AM +00:00 
[email protected]/7/2017 5:00:33 AM +00:00 [email protected]/7/2017 5:00:32 AM +00:00 
1

あなたの質問は完全にシナリオを説明していないので次の放出値を最後に放出された値または最後に放出された値または他のものと比較する。 私は一般的な方法で解決策に到達します。

例はRxJavaです。

次のようなfilter()オペレータと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(); 

。最後に放出された値を探している場合は、doOnNext()演算子(単純な場合)を使用して最後に放出された値を停止することができます。または、放出された値をリストとチェックに保存する必要があります。

私はそれが役に立ちそうです。

3

あなたは、本質的に、個々のアイテム

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

それは私がそれをやる方法です。 –

+0

RxJSにはうまく見えます - RxJava2はgroupByUntil演算子を持っていないようです:) –

+0

なぜrxjsとrx-javaの両方をリストアップしたのか分かりませんでした。 JavaにC#バージョンを移植することができます:https://github.com/Reactive-Extensions/Rx.NET/blob/83710cfa9395355af6eb908f96261ea632a49009/Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupByUntil.cs – Brandon

関連する問題