C# 可观察<;IEnumerable>;获取序列元素之间的差异
我有一个可观测的物体,它发出一系列的IEnumerables 1:C# 可观察<;IEnumerable>;获取序列元素之间的差异,c#,system.reactive,C#,System.reactive,我有一个可观测的物体,它发出一系列的IEnumerables 1:[1,2,3,4] 2:[1,3,4] 3:[1,5,6] 等等 我想尝试从中创建两个观测值: 发出新添加元素的IEnumerable的元素: 1:[1,2,3,4] 2:[] 3:[5,6] 等等 发出新移除元素的IEnumerable的元素: 1:[] 2:[2] 3:[3,4] 等等 有没有一种方法可以使用System.Responsive来实现这一点,而不必依赖于保留一个单独的数据结构来比较更改?如果使用Obser
[1,2,3,4]
2:[1,3,4]
3:[1,5,6]
等等
我想尝试从中创建两个观测值:
- 发出新添加元素的IEnumerable的元素:
[1,2,3,4]
2:[]
3:[5,6]
等等
- 发出新移除元素的IEnumerable的元素:
[]
2:[2]
3:[3,4]
等等
有没有一种方法可以使用System.Responsive来实现这一点,而不必依赖于保留一个单独的数据结构来比较更改?如果使用
Observable.Zip
和Enumerable,就相当简单了。除了
可以轻松比较元素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));
}
}
公共静态类IObservableIEnumerableExtensions
{
公共静态IObservable GetAddedElements(此IObservable源)
{
返回source.Zip(source.StartWith(Enumerable.Empty()),(更新的,旧的)=>newer.Except(旧的));
}
公共静态IObservable GetRemovedElements(此IObservable源)
{
返回source.Zip(source.StartWith(Enumerable.Empty()),(较新,较旧)=>older.Except(较新));
}
}
下面是一些跑步者代码:
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 });
var source=新主题();
var addedElements=source.GetAddedElements();
var removedElements=source.GetRemovedElements();
addedElements.Dump()//使用Linqpad
removedElements.Dump()//使用Linqpad
source.OnNext(新的int[]{1,2,3,4});
source.OnNext(新的int[]{1,3,4});
source.OnNext(新的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); });
}
public static IObservable cumulativeheaded(此IObservable src){
var memadd=new HashSet();
返回src.Select(x=>x.Where(n=>memadd.Add(n));
}
公共静态IObservable CumulativeRemoved(此IObservable src){
var memdiff=new HashSet();
返回src.Select(x=>{foreach(x中的var n)memdiff.Add(n);返回memdiff.AsEnumerable().Except(x);});
}
}否。为什么所有删除的元素第3行中没有2个?不包含5的第4行会生成什么?我想他指的是“新删除的元素”而不是“所有删除的元素”。你的答案假设是新添加的元素,但我认为如果源行2是
[3,4]
,而添加的输出行3应该是[5,6],那么除了之外的就行不通了
still.@NetMage Shlomo是正确的,因为我指的是新删除的元素。我不知道我为什么在那里放屁,我的坏朋友!最终,我在寻找如何将序列中的元素与之前的元素进行比较。谢谢你们的回答!在前面用一个额外的空元素创建一个新的可观察对象,然后将其用作n-1是天才!我一直试图调用源observable的Last
和/或Latest
元素,但这两个元素都没有用。再次感谢!我建议将查询更改为source.Publish(s=>s.Zip(s.StartWith(Enumerable.Empty()),(newer,older)=>newer.Except(older))代码>以避免多个订阅可能出现的任何问题。