Example #1
0
    public Cache(IObservable <T> newElements, IEnumerable <T> seedElements, Func <T, TKey> keySelector)
    {
        var agg = new State {
            Cache = seedElements.ToImmutableDictionary(keySelector), Value = default(T)
        };

        _source = newElements
                  // Use the Scan operator to update the dictionary of values based on key and use the anonymous tuple to pass this and the current item to the next operator
                  .Scan(agg, (tuple, item) => new State {
            Cache = tuple.Cache.SetItem(keySelector(item), item), Value = item
        })
                  // Ensure we always have at least one item
                  .StartWith(agg)
                  // Share this single subscription to the above with all subscribers
                  .Publish();
        _observable = _source.Publish(source =>
                                      // ... concatting ...
                                      Observable.Concat(
                                          // ... getting a single collection of values from the cache and flattening it to a series of values ...
                                          source.Select(tuple => tuple.Cache.Values).Take(1).SelectMany(values => values),
                                          // ... and the returning the values as they're emitted from the source
                                          source.Select(tuple => tuple.Value)
                                          )
                                      );
    }