Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可观察<;IEnumerable>;获取序列元素之间的差异_C#_System.reactive - Fatal编程技术网

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

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

我有一个可观测的物体,它发出一系列的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来实现这一点,而不必依赖于保留一个单独的数据结构来比较更改?

如果使用
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))以避免多个订阅可能出现的任何问题。