I'm learning rx in .NET and i've got the following requirements:
- A sequence of strings is coming from an API. They are coming in different time intervals which I don't know. Sometimes there are coming 5 strings within a second, sometimes there is only coming 1 string within 5 seconds.
- The strings are basically five commands: "start", "stop", "left", "right", "back". There are other commands incoming, but they can be filtered out.
- The program should now execute whenever a command comes in.
- If the same command is incoming within a given period of time (let's say 2 seconds), the command should only be executed once. If another command is incoming within this period, it should be executed immediatly. If the same command like the previous executed one is incoming after the given period of time, it should be executed.
- There is no timestamp assigned with the incoming data (but this can be done if needed).
So given the example data:
using System; using System.Reactive.Linq; namespace ConsoleApp1 { class Program { static void Main(string[] args) { var results = new[] { "right", //1 "left", //2 "right", //3 "right", //4 "left", //5 "right", //6 "right", //7 "right", //8 "left" //9 }; var observable = Observable.Generate(0, x => x < results.Length, x => x + 1, x => results[x], x => TimeSpan.FromSeconds(1)).Timestamp(); observable.Subscribe(...); Console.ReadKey(); } } } The result should be:
right //1 left //2 right //3 left //5 right //6 right //8 left //9 String 4 has been skipped because its only 1 second to the last "right", so has string 7. However, string 8 has not been skipped cause there are 2 seconds to string 6.
Possible solutions:
I tried to use a windowing function to skip entries, but this will skipp all strings even if they aren't the same value:
observable.Publish(ps => ps.Window(() => ps.Delay(TimeSpan.FromSeconds(2))) .SelectMany(x => x.Take(1))).Subscribe(f => Console.WriteLine(f.Value)); I also tried to add timestamps to each value and check them in a DistinctUntilChanged() EqualityComparer, but this seems also not to work as expected.
right, left, right, leftall .1 seconds apart, should all 4 messages get emitted, or just 2?