簡體   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