Learning Rx: How can I analyze the observed sequence of characters in the observed sequence of strings?

This is probably very simple, but I'm at the bottom of the learning curve with Rx. I spent several hours reading articles, watching videos and writing code, but I seem to have a mental block on what seems to be very simple.

I am collecting data from a serial port. I used Observable.FromEventPatternto capture an event SerialDataReceivedand convert it into an observable sequence of characters. So far so good.

Now I want to analyze this sequence of characters based on separator characters. There are no new lines, but each “packet” of data is surrounded by a preamble and a terminator, as single characters. For the argument, suppose these are parentheses {and }.

So, if I get a sequence of characters j u n k { H e l l o } j u n kin my sequence of characters, then I want to emit either Hello, or {Hello}in my sequence of strings.

I probably missed something simple, but I can’t even figure out how to approach this. Any suggestions please?

+4
source share
2 answers

This can be easily done with Publishand Buffer:

var source = "junk{Hello}junk{World}junk".ToObservable();
var messages = source
    .Publish(o =>
    {
        return o.Buffer(
            o.Where(c => c == '{'),
            _ => o.Where(c => c == '}'));
    })
    .Select(buffer => new string(buffer.ToArray()));
messages.Subscribe(x => Console.WriteLine(x));
Console.ReadLine();

The result of this:

{Hello}
{World}

, Buffer. Publish , , Buffer, .

source:  junk{Hello}junk{World}junk|
opening: ----{----------{----------|
closing:     ------}|
closing:                ------}|
+6

", (TAccumulate - string), reset "" , . ( ). ,

j
ju
jun
junk
junk{
junk{h
junk{hi
junk{hi}
j
ju
...

Where, , }

, , , junk.

, ,

IObservable<string> packetReceived = 
  serialPort.CharReceived
    .Scan(YourAggregationFunction)
    .Where(s => s.EndsWith("}"))
    .Select(s => s.EverythingAfter("{"));

( EverythingAfter , ).

, , , IEnumerable string , ..

foreach (s in "junk{hi}hunk{ji}blah".Scan(YourAggregationFunction))
  Console.WriteLine(s);

,

static void Main(string[] args) {
    var stuff = "junk{hi}junk{world}junk".ToObservable()
        .Scan("", (agg, c) => agg.EndsWith("}") ? c.ToString() : agg + c)
        .Where(s => s.EndsWith("}"))
        .Select(s => s.Substring(s.IndexOf('{')));
    foreach (var thing in stuff.ToEnumerable()) {
        Console.WriteLine(thing);
    }
}
0

All Articles