繁体   English   中英

学习Rx:如何将可观察的字符序列解析为可观察的字符串序列?

[英]Learning Rx: How can I parse an observable sequence of characters into an observable sequence of strings?

这可能非常简单,但我在Rx的学习曲线底部。 我花了几个小时阅读文章,观看视频和编写代码,但我似乎对一些似乎应该非常简单的事情有一些心理障碍。

我正在从串口收集数据。 我使用Observable.FromEventPattern捕获SerialDataReceived事件并将其转换为可观察的字符序列。 到现在为止还挺好。

现在,我想基于分隔符来解析该字符序列。 没有涉及新行,但每个“数据包”数据都由前导码和终结符包围,两个单个字符。 为了论证,我们可以说它们是大括号{}

所以,如果我得到的字符序列j u n k { H e l l o } j u n k在我的字符序列,那么我想发出任何Hello{Hello}我的字符串序列。

我可能错过了一些简单的东西,但我甚至无法弄清楚如何处理这个问题。 有什么建议吗?

使用PublishBuffer可以轻松完成此操作:

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

这个输出是:

{Hello}
{World}

我们的想法是,您可以在调用Buffer使用以下打开和关闭选择器。 使用Publish是为了确保所有三个Buffer ,开放选择器和结束选择器共享相同的订阅。

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

使用“ 扫描”将您的远程接收值聚合到聚合字符串中( TAccumulate是一个string ),并在每次获得结束括号时将该字符串重置为"" (我将把实现聚合功能的工作留给你)。 这会产生类似的观察

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

然后你可以使用Where只发出结尾的那些}

然后最后使用Select来摆脱junk

所以完整,应该是

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

(我将EverythingAfter留给你实施)。

只是注意,当您正在尝试聚合函数时,使用stringIEnumerable接口来测试它可能更容易,即

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM