TL;DR 版本:
有没有一种方法可以枚举仅延迟一个元素(可以是附加元素或缺失元素)的两个列表,并在匹配所有其他元素的同时判断哪个元素发生了变化?
我类有一个List<View>
属性,它是从 List<Model>
创建的通过构造函数注入(inject)。每个View
包装其各自的 Model
作为公共(public)属性(property)。
在相同的范围内,有一个void Update(List<Model> newList)
例程,它接收另一个列表 Model
具有以下条件:相同 List<Model>
和以前一样,恰好加或减一个元素。那是因为 Update
每次在其他地方的数据绑定(bind)列表中添加或删除项目时都会调用,应用程序只能选择一次添加/删除一个元素。
Update
的动机操作,而不是简单地用新列表替换旧列表的模型(包装在 View 中),是View
classes store state,所以我想替换它们的模型,但保留它们的状态 - 无论如何都不会存储在模型中。
问题是:如果有新模型,我必须添加新 View ,当相应模型不存在时,我必须删除相应 View ,并且我必须将现有 View 与其现有模型匹配,添加或删除的元素除外。我不确定该怎么做。
所以我在考虑将列表第一个元素中的模型与新列表的第一个元素进行比较,如果它们匹配,则转到第二个元素,依此类推。在某一点上,它们会有所不同,但这可能是因为添加了一个元素(然后剩余的元素将移动一个索引),或者由于删除了一个元素(在这种情况下,剩余的元素将向下移动,并且不同的元素实际上是列表中已经存在的元素)。
是否有任何明智的方法来判断第一个不同的元素是由于添加还是删除引起的?
最佳答案
您可以使用 Except()
扩展名,例如:
List<Model> models = new List<Model>();
List<View> views = new List<View>();
然后您可以获得所需的添加/删除项目:
//If models.Count > views.Count
var addedModel = models.Except(views.Select(v => v.Model)).FirstOrDefault();
//If views.Count > models.Count
var modelToRemove = views.Select(v => v.Model).Except(models).FirstOrDefault();
var viewToRemove = views.Single(v => v.Model == modelToRemove);
也许您需要传递一个 IEqualityComparer<Model>
用于自定义比较。
如果列表是或可以根据某些标准排序,你可以按照你在问题中所说的去做,找到列表不同的索引:
//for simplicity sorts the lists according to some 'Id'
models.Sort((a, b) => a.Id.CompareTo(b.Id));
views.Sort((a, b) => a.Model.Id.CompareTo(b.Model.Id));
然后,获取比较值的索引:
var index = Enumerable.Range(0, Math.Min(models.Count, views.Count))
.First(i => !Model.Equals(models[i], views[i].Model));
//If models.Count > views.Count
var addedModel = models[index];
//If views.Count > models.Count
var viewToRemove = views[index];
关于c# - 比较两个列表以在其中一个列表中查找添加或删除的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36701657/