Rx operator to distinct sequences

后端 未结 3 2030
后悔当初
后悔当初 2021-02-20 17:23

IMPORTANT: for a description of the results and some more details, please have a look also to my answer

I need to group and filter a sequence of objects

3条回答
  •  有刺的猬
    2021-02-20 18:09

    Not sure if this is exactly what you want, but it seems to support your use cases.

    First, let's define the base class to use (you can easily modify this to suit your needs):

    public class MyEvent
    {
        public string NetworkAddress { set; get; }
        public string EventCode { set; get; }
    }
    

    Let's set up your devices as an array of IObservable - you may have these available differently, and the below would need to change to accommodate that of course. These devices will each produce a value with a random delay between 0.5 and 1.5 seconds.

    var deviceA = new MyEvent[] { new MyEvent() {NetworkAddress = "A", EventCode = "1"},
                                  new MyEvent() {NetworkAddress = "A", EventCode = "1"},
                                  new MyEvent() {NetworkAddress = "A", EventCode = "2"} };
    
    var deviceB = new MyEvent[] { new MyEvent() {NetworkAddress = "B", EventCode = "1"},
                                  new MyEvent() {NetworkAddress = "B", EventCode = "2"},
                                  new MyEvent() {NetworkAddress = "B", EventCode = "2"},
                                  new MyEvent() {NetworkAddress = "B", EventCode = "3"} };   
    
    var random = new Random();                                 
    
    var deviceARand = deviceA.ToObservable().Select(a => Observable.Return(a).Delay(TimeSpan.FromMilliseconds(random.Next(500,1500)))).Concat();
    var deviceBRand = deviceB.ToObservable().Select(b => Observable.Return(b).Delay(TimeSpan.FromMilliseconds(random.Next(500,1500)))).Concat();
    
    var devices = new IObservable[] { deviceARand, deviceBRand };
    

    Now let's take all of these individual device streams, make them 'distinct', and merge them into a single master stream:

    var stream = devices.Aggregate(Observable.Empty(), (acc, device) => acc.DistinctUntilChanged(a => a.EventCode).Merge(device));
    

    Once you have that, getting this stream to be consumed periodically is just a matter of buffering it with Buffer:

    stream.Buffer(TimeSpan.FromSeconds(1)).Subscribe(x => { /* code here works on a list of the filtered events per second */ });
    

提交回复
热议问题