可观察<IEnumerable>获取序列元素之间的差异



我有一个发出一系列 IEnumerables 的可观察量

1:[1,2,3,4]

2:[1,3,4]

3:[1,5,6]

等。。

我想尝试从中创建两个可观察量:

  • 一个发出 IE无数新添加元素的元素:

1:[1,2,3,4]

2:[]

3:[5, 6]

等。。

  • 一个发出 IE无数新删除的元素:

1:[]

2:[2]

3:[3,4]

等。。

有没有办法使用 System.Reactive 来做到这一点,而不必依赖保持单独的数据结构来比较更改?

如果您使用Observable.ZipEnumerable.Except轻松地将元素 n 与元素 n-1 进行比较,这相当简单。

public static class IObservableIEnumerableExtensions
{
public static IObservable<IEnumerable<T>> GetAddedElements<T>(this IObservable<IEnumerable<T>> source)
{
return source.Zip(source.StartWith(Enumerable.Empty<T>()), (newer, older) => newer.Except(older));
}
public static IObservable<IEnumerable<T>> GetRemovedElements<T>(this IObservable<IEnumerable<T>> source)
{
return source.Zip(source.StartWith(Enumerable.Empty<T>()), (newer, older) => older.Except(newer));
}
}

下面是一些运行器代码:

var source = new Subject<IEnumerable<int>>();
var addedElements = source.GetAddedElements();
var removedElements = source.GetRemovedElements();
addedElements.Dump();   //Using Linqpad
removedElements.Dump(); //Using Linqpad
source.OnNext(new int[] { 1, 2, 3, 4 });
source.OnNext(new int[] { 1, 3, 4 });
source.OnNext(new int[] { 1, 5, 6 });

如果您希望从序列的开头开始累积添加和删除,则需要一些东西来记住之前发生的事情。

public static IObservable<IEnumerable<T>> CumulativeAdded<T>(this IObservable<IEnumerable<T>> src) {
var memadd = new HashSet<T>();
return src.Select(x => x.Where(n => memadd.Add(n)));
}
public static IObservable<IEnumerable<T>> CumulativeRemoved<T>(this IObservable<IEnumerable<T>> src) {
var memdiff = new HashSet<T>();
return src.Select(x => { foreach (var n in x) memdiff.Add(n); return memdiff.AsEnumerable().Except(x); });
}

}

相关内容

  • 没有找到相关文章

最新更新