public static IReactiveDictionary <TKey, TValue> Where <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict, Func <TKey, TValue, bool> selector) { return(dict .AsObservable() .Select(changes => changes .Select(change => { if (change.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate && !selector(change.Key, change.Value)) { if (dict.TryGetValue(change.Key, out var value)) { return new ReactiveDictionaryChange <TKey, TValue>(change.Key, value, ReactiveDictionaryChangeReason.Remove); } else { return null; } } else { return change; } }) .Where(x => x != null) .ToArray() ) .Where(x => x.Any()) .ToDictionary((TKey key, out TValue value) => { if (!dict.TryGetValue(key, out value)) { return false; } return selector(key, value); })); }
public static IReactiveSet <KeyValuePair <TKey, TValue> > ToSet <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict) { return(dict.AsObservable().SelectMany(changes => changes.SelectMany(change => { if (change.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate) { if (dict.TryGetValue(change.Key, out var oldValue)) { // Updating, so remove the old pair and add the new one return new[] { new ReactiveSetChange <KeyValuePair <TKey, TValue> >( ReactiveSetChangeReason.Remove, new[] { new KeyValuePair <TKey, TValue>(change.Key, oldValue) } ), new ReactiveSetChange <KeyValuePair <TKey, TValue> >( ReactiveSetChangeReason.Add, new[] { new KeyValuePair <TKey, TValue>(change.Key, change.Value) } ) }; } } // Just adding or removing return new[] { new ReactiveSetChange <KeyValuePair <TKey, TValue> >( change.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate ? ReactiveSetChangeReason.Add : ReactiveSetChangeReason.Remove, new[] { new KeyValuePair <TKey, TValue>(change.Key, change.Value) } ) }; })) .ToReactiveSet(pair => dict.TryGetValue(pair.Key, out var value) && value.Equals(pair.Value))); }
public static IReactiveDictionary <TKey, TNewValue> SelectEquatable <TKey, TValue, TNewValue>( this IReactiveDictionary <TKey, TValue> dict, Func <TKey, TValue, TNewValue> selector) where TNewValue : IEquatable <TNewValue> { return(dict.AsObservable().Select(changes => changes.Select(change => { if (change.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate) { return new ReactiveDictionaryChange <TKey, TNewValue>(change.Key, selector(change.Key, change.Value), ReactiveDictionaryChangeReason.AddOrUpdate); } else if (dict.TryGetValue(change.Key, out var value)) { return new ReactiveDictionaryChange <TKey, TNewValue>(change.Key, selector(change.Key, change.Value), ReactiveDictionaryChangeReason.Remove); } else { return null; } })) .ToDictionary((TKey key, out TNewValue value) => { if (dict.TryGetValue(key, out var oldValue)) { value = selector(key, oldValue); return true; } value = default; return false; })); }
public static IObservable <TKey> ElementsRemoved <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict) { return(dict .AsObservable() .Select(x => x.Where(y => y.ChangeReason == ReactiveDictionaryChangeReason.Remove)) .SelectMany(x => x) .Select(x => x.Key)); }
public static IObservable <KeyValuePair <TKey, TValue> > ElementsAddedOrUpdated <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict) { return(dict .AsObservable() .Select(x => x.Where(y => y.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate)) .SelectMany(x => x) .Select(x => new KeyValuePair <TKey, TValue>(x.Key, x.Value))); }
public static IObservable <TResult> Aggregate <TKey, TValue, TResult>( this IReactiveDictionary <TKey, TValue> dict, TResult seed, Func <TResult, TKey, TValue, TResult> addFunc, Func <TResult, TKey, TValue, TResult> removeFunc) { if (dict == null) { throw new ArgumentNullException(nameof(dict)); } if (addFunc == null) { throw new ArgumentNullException(nameof(addFunc)); } if (removeFunc == null) { throw new ArgumentNullException(nameof(removeFunc)); } return(Observable.Create <TResult>(observer => { var current = seed; observer.OnNext(current); IDisposable sub = null; sub = dict .AsObservable() .Subscribe( x => { foreach (var change in x) { try { if (change.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate) { current = addFunc(current, change.Key, change.Value); } else { current = removeFunc(current, change.Key, change.Value); } } catch (Exception ex) { observer.OnError(ex); sub?.Dispose(); return; } } observer.OnNext(current); }, observer.OnError, observer.OnCompleted ); return sub; }) .DistinctUntilChanged()); }
public static IObservable <TValue> LatestValue <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict, TKey key) { return(dict .AsObservable() .SelectMany(changes => changes .Where(x => x.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate) .Where(x => x.Key.Equals(key))) .Select(x => x.Value)); }
public static IReactiveDictionary <TKey, TValue> SubscribeMany <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict, Func <TKey, TValue, IDisposable> subscriptionFactory) { var seq = Observable.Create <IEnumerable <ReactiveDictionaryChange <TKey, TValue> > >(observer => { Dictionary <KeyValuePair <TKey, TValue>, IDisposable> subs = new Dictionary <KeyValuePair <TKey, TValue>, IDisposable>(); var disposable1 = dict.AsObservable().Subscribe( changes => { foreach (var change in changes) { if (dict.ContainsKey(change.Key)) { if (subs.TryGetValue(change.Pair, out var sub)) { sub.Dispose(); } } if (change.ChangeReason == ReactiveDictionaryChangeReason.AddOrUpdate) { subs[change.Pair] = subscriptionFactory(change.Key, change.Value); } } observer.OnNext(changes); }, observer.OnError, observer.OnCompleted ); return(() => { disposable1.Dispose(); foreach (var sub in subs) { sub.Value.Dispose(); } }); }); return(seq.ToDictionary(dict.TryGetValue)); }
public static IReactiveDictionary <TKey, TValue> Join <TKey, TValue>(this IReactiveDictionary <TKey, TValue> dict, IReactiveDictionary <TKey, TValue> dict2) { var obs1 = dict.AsObservable().Select(changes => changes.Select(change => { if (change.ChangeReason == ReactiveDictionaryChangeReason.Remove) { if (dict2.TryGetValue(change.Key, out var value)) { return(new ReactiveDictionaryChange <TKey, TValue>(change.Key, value, ReactiveDictionaryChangeReason.AddOrUpdate)); } } return(change); })); var obs2 = dict2.AsObservable().Select(changes => changes.Select(change => { if (change.ChangeReason == ReactiveDictionaryChangeReason.Remove) { if (dict2.TryGetValue(change.Key, out var value)) { return(new ReactiveDictionaryChange <TKey, TValue>(change.Key, value, ReactiveDictionaryChangeReason.AddOrUpdate)); } } return(change); })); return(obs1.Merge(obs2) .Select(x => x.ToArray()) .Where(x => x.Length > 0) .ToDictionary((TKey key, out TValue value) => { if (dict.TryGetValue(key, out value)) { return true; } return dict2.TryGetValue(key, out value); })); }
public static ICollectedReactiveDictionary <TKey, TValue> ToConcurrentDictionary <TKey, TValue>( this IReactiveDictionary <TKey, TValue> dict) { return(new DependentReactiveDictionary <TKey, TValue>(dict.AsObservable(), new ConcurrentDictionary <TKey, TValue>())); }
public static ICollectedReactiveDictionary <TKey, TValue> ToDictionary <TKey, TValue>( this IReactiveDictionary <TKey, TValue> dict, IDictionary <TKey, TValue> inner) { return(new DependentReactiveDictionary <TKey, TValue>(dict.AsObservable(), inner)); }