Filtering operators act as the where
operators of any LINQ
query. They reduce, take, or peek a value (or multiple values) from a sequence when messages comply with a given filtering function.
The easiest filtering operator, filter, simply applies a filtering condition that allows or prevents messages from flowing throughout the newly created sequence. In Rx, the filter operator in made by using the Where
extension method like in any other LINQ
query.
Here's an example:
var s12 = new Subject<string>(); var filtered = s12.Where(x => x.Contains("e")); filtered.Subscribe(Console.WriteLine); s12.OnNext("Mr. Brown"); s12.OnNext("Mr. White");
The distinct
operator, similar to what happens in any SQL statement, creates a new sequence that prevents duplicated values from flowing out from the source sequence.
Here's an example:
var s13 = new Subject<string>(); var distinct = s13.Distinct(); distinct.Subscribe(Console.WriteLine); s13.OnNext("value1"); s13.OnNext("value2"); s13.OnNext("value1"); s13.OnNext("value2");
Different from the simple distinct operator, the DistinctUntilChanged
operator avoids duplicated values flowing into a new sequence only when those duplicated values are contiguous.
This is a powerful operator for any raw value sampling, such as when dealing with analog or digital sensors from IoT applications, preventing high rate sampling from creating multiple duplicated values because the sampling rate is higher than the value change rate.
Here's an example:
var s24 = new Subject<string>(); var distinct = s24.DistinctUntilChanged(); distinct.Subscribe(Console.WriteLine); s24.OnNext("value1"); //ok s24.OnNext("value2"); //ok s24.OnNext("value2"); //ignored s24.OnNext("value3"); //ok s24.OnNext("value4"); //ok s24.OnNext("value1"); //ok s24.OnNext("value2"); //ok s24.OnNext("value2"); //ignored s24.OnNext("value3"); //ok s24.OnNext("value4"); //ok
Bear in mind that the operator avoids duplicated values when these flow sequentially, otherwise duplicates may exist. Thus, in the preceding example, we saw that we can flow out messages from 1
to 4
two times. Only the two duplicates are ignored.
The ElementAt
operator makes available accessing a new sequence that will flow a single message when its index in the source sequence equals the requested index.
Here's an example:
var s13 = new Subject<string>(); var indexed = s13.ElementAt(2); indexed.Subscribe(Console.WriteLine); s13.OnNext("value1"); //ignored s13.OnNext("value2"); //ignored s13.OnNext("value3"); //OK s13.OnNext("value4"); //ignored
The Skip
operator creates a new sequence that will skip some messages from the source sequence before it starts flowing messages.
Here's an example:
var s14 = new Subject<string>(); var skip = s14.Skip(2); skip.Subscribe(Console.WriteLine); s14.OnNext("value1"); //ignored s14.OnNext("value2"); //ignored s14.OnNext("value3"); //ok s14.OnNext("value4"); //ok
The Take
operator, as the opposite of the skip operator, creates a new sequence that will flow only an initial amount of messages from the source sequence.
Here's an example:
var s15 = new Subject<string>(); var take = s15.Take(2); take.Subscribe(Console.WriteLine); s15.OnNext("value1"); //ok s15.OnNext("value2"); //ok s15.OnNext("value3"); //ignored s15.OnNext("value4"); //ignored
18.226.251.70