2016-11-16 54 views
0

我有一個問題A cache serving updates and new values as 「DistinctLatest」 and full cache contents upon subscription,這是由社區處理。有人提出了一個問題,即上述問題中定義的緩存和替換值的實際目標可以用.DistinctLatest運算符來定義。應該如何去實現Rx中的DistinctLatest(和緩存)操作符?

行!似乎沒有太多關於這樣的運營商的討論。在搜索和思考時,我發現ReactiveX: Group and Buffer only last item in each group,這是非常接近的。爲了模擬天生原來的問題,我試着寫緩存操作者

/// <summary> 
/// A cache that keeps distinct elements where the elements are replaced by the latest. 
/// </summary> 
/// <typeparam name="T">The type of the result</typeparam> 
/// <typeparam name="TKey">The type of the selector key for distinct results.</typeparam> 
/// <param name="newElements">The sequence of new elements.</param> 
/// <param name="seedElements">The seed elements when the cache is started.</param> 
/// <param name="replacementSelector">The replacement selector to choose distinct elements in the cache.</param> 
/// <returns>The cache contents upon first call and changes thereafter.</returns> 
public static IObservable<T> Cache<T, TKey>(this IObservable<T> newElements, IEnumerable<T> seedElements, Func<T, TKey> replacementSelector) 
{ 
    var s = newElements.StartWith(seedElements).GroupBy(replacementSelector).Select(groupObservable => 
    { 
     var replaySubject = new ReplaySubject<T>(1); 
     groupObservable.Subscribe(value => replaySubject.OnNext(value)); 

     return replaySubject; 
    }); 

    return s.SelectMany(i => i);    
} 

但這樣做的測試似乎並不要麼做的伎倆。看起來好像是在開始時訂閱了初始值和更新(以及新值)。而如果最後訂閱了一個,則只記錄替換的種子值。

現在,我想知道一般的DistinctLast操作符,我認爲這個,但它不起作用,然後這個「緩存」添加的是種子值和組的扁平化,但這不是測試告訴。我也嘗試過一些分組和.TakeLast(),但沒有骰子。

如果有人有指點或思考這個問題,我很高興,並希望這通常是有益的。

+1

如果你提供了一個失敗的單元測試,那麼社區可以實現運營商,使其通過。 (我認爲這只是GroupBy + Replay(1) –

+0

我會!我現在被綁在一個會議上(我想我會從鏈接的問題中進行測試) – Veksi

回答

1

@LeeCampbell爲此做了大部分工作。查看其他引用的問題。無論如何,這裏的代碼:

public static class RxExtensions 
{ 
    public static IObservable<T> DistinctLatest<T, TKey>(this IObservable<T> newElements, IEnumerable<T> seedElements, Func<T, TKey> replacementSelector) 
    { 
     return seedElements.ToObservable() 
      .Concat(newElements) 
      .GroupBy(i => replacementSelector) 
      .SelectMany(grp => grp.Replay(1).Publish().RefCoun‌​t()); 
    } 
} 
+0

做得好,在這裏添加這個,雖然對於其他讀者來說, 'seedElements'從上一個問題中流了出來,應該不會在這裏看到它。 – Veksi