2016-02-11 48 views
1

我已經對反應性linq(也稱爲Rx.NET)做了一些研究。我已經看到SelectMany方法的行爲如下最終結果:展平observable中的內容,使其從多個流轉到單個流。我的問題是,是否有一種方法在完全相反的方向上行事?這意味着在將多個事件放入一個可觀察的事件(multiplexing)後,如何實現這一點?我知道GroupBy與我請求的行爲非常相似,除了一件事情不存在:我想要一個可能還沒有發佈的密鑰的可觀察對象。Rx.net中SelectMany的相反結果

我正在考慮自己實施行爲,但如果有機會,我錯過了這種方法的存在,請告訴我我錯了,它確實存在!

+0

我在想'GroupBy'或'Where'會做詭計。你能張貼代碼說明如何/爲什麼這些不足? – Shlomo

+0

使用一個簡單的'.Where'是對這個最明顯的答案,因爲分組和投影一個還沒有出現的組是一樣的,只是做'.Where'。你能詳細說明嗎? – Enigmativity

回答

2

你是對的GroupBy是你想要的。設置它可以很容易地提前訂閱任何密鑰。只是這樣做:

IObservable<int> oddNumbers = 
    Observable 
     .Range(0, 10) 
     .GroupBy(x => x % 2) 
     .Where(gx => gx.Key == 1) 
     .Merge(); 

如果我同意,我得到:

 
1 
3 
5 
7 
9 

然而,這一點的時候,因爲這是浪費直接等價的:

IObservable<int> oddNumbers = 
    Observable 
     .Range(0, 10) 
     .Where(x => x % 2 == 1); 

我可以看到它可能有用的唯一方法是如果你這樣做:

IConnectableObservable<IGroupedObservable<int, int>> groupedNumbers = 
    Observable 
     .Range(0, 10) 
     .GroupBy(x => x % 2) 
     .Publish(); 

Func<IConnectableObservable<IGroupedObservable<int, int>>, int, IObservable<int>> anyProject = 
    (source, key) => 
     source 
      .Where(gx => gx.Key == key) 
      .Merge(); 

IObservable<int> oddNumbers = anyProject(groupedNumbers, 1); 

oddNumbers.Subscribe(x => Console.WriteLine(x)); 

groupedNumbers.Connect(); 

這仍然給我奇數,但我現在可以創建偶數可觀察而無需開始新的分組。

3

GroupBy是你正在尋找的東西,但正如你指出的那樣,它在預先創建「已知」羣體方面確實不足。不過我想你可能是創意和種子與價值觀的順序爲每個這些已知的組這樣的:

如果來源是這樣

Observable.Interval(TimeSpan.FromMilliseconds(100)) 
    .GroupBy(i => i % 4) 

您可以修改,要成爲像

var seed = new[] { 0L, 1L, 2L, 3L }.ToObservable(); 
Observable.Concat(seed, Observable.Interval(TimeSpan.FromMilliseconds(100))) 
    .GroupBy(i => i % 4) 
    .Select(grp=>grp.Skip(1)) //Ignore the first/seed value.