2017-09-25 46 views
2

我有一個包含關鍵字的反應性列表。用戶可以添加或刪除該列表中的關鍵字。該應用需要驗證用戶是否鍵入了其中一個關鍵字。 已經有類似的帖子,但它並沒有在考慮採取靈活的清單: Using Reactive Extension for certain KeyPress sequences?驗證用戶是否從具有反應性擴展的反應性列表中鍵入單詞

var keyElements = new ReactiveList<KeyElement>(); 
IObservable<IObservable<int>> rangeToMax = Observable.Merge(keyElements.ItemsAdded, keyElements.ItemsRemoved).Select(obs => Observable.Range(2, keyElements.Select(ke => ke.KeyTrigger.Length).Max())); 


IObservable<IObservable<string>> detectedKeyTrigger = rangeToMax 
    .Select(n => _keyPressed.Buffer(n, 1)) 
    .Merge().Where(m => keyElements.Where(ke => ke.KeyTrigger == m).Any()); 
//Here I want to end up with IObservable<string> instead of IObservable<IObservable<string>> 

我可以每次都重新分配detectedKeyTrigger元素在反應列表的變化擺脫外的IObservable的,但後來我失去了我所有的訂閱。 那麼,我怎樣才能得到一個字符串的可觀察?

+0

你能解決你的代碼嗎?它在'.Buffer(n,1)'後面或'.Any())'後面有一個括號。那你能不能請[mcve]?我希望能夠編譯和運行你的代碼。 – Enigmativity

+0

@Enigmativity感謝花時間在我的問題上。我對示例代碼做了一個小小的更新。同時,JonStødle提供了我正在尋找的答案。 – jtourlamain

+0

不用擔心。將來,發佈[mcve]會對你有好處。這會有很大的幫助。 – Enigmativity

回答

4

首先,MaxAny都有重載,它們分別帶有一個選擇器和一個謂詞。這否定了Select的需要。

接下來,我改變了Observable.Merge使用的ReactiveListChanged財產是INotifyCollectionChanged在Rx版本。我也改變了Select來產生IEnumerableints。它只是感覺更正確™。

var keyElements = new ReactiveList<KeyElement>(); 
IObservable<IEnumerable<int>> rangeToMax = keyElements.Changed 
    .Select(_ => Enumerable.Range(2, keyElements.Max(keyElement => keyElement.KeyTrigger.Length)); 


IObservable<IObservable<string>> detectedKeyTrigger = rangeToMax. 
    .Select(range => range 
     .Select(length => _keyPressed.Buffer(length, 1).Select(chars => new string(chars.ToArray()))) // 1 
     .Merge() // 2 
     .Where(m => keyElements.Any(ke => ke.KeyTrigger == m)) // 3 
    .Switch(); // 4 
  1. 創建IObservable<string>發射最後n字符由用戶鍵入。對於每次組合
  2. 的可能長度創建這樣一個觀察的合併在IEnumerable<IObservable<string>>的觀測到一個Observable<string>
  3. 只有讓馬赫的KeyTrigger S的一個通過
  4. 作爲rangeToMax.Select串產生IObservable<IObservable<string>>我們使用Switch只能訂閱最近的IObservable<string>IObservable<IObservable<string>>產生。