LINQ-比较列表字典以查找新的和更改的对象

本文关键字:对象 查找 比较 列表 字典 LINQ- | 更新日期: 2023-09-27 18:15:34

这是我的问题:

我有两本结构相同的词典:

Dictionary<string, List<Object>> Existing
Dictionary<string, List<Object>> New

基本上,我需要做的是首先根据关键字找到任何在New中但不在Existing中的List<Object>,然后在New中包含的每个List<Object>中找到任何在其对应的Existing List<Object>中不存在的对象,或者根据Object中的许多属性(当然还有字典关键字(更改的对象。

我目前正在通过循环和单独检查每个对象来完成这项工作,但我认为必须有一种更好的方法来使用LINQ。

希望这是清楚的,但如果你需要更多的信息,请告诉我。

谢谢。

LINQ-比较列表字典以查找新的和更改的对象

对于字典中的新条目和条目的List<object>:中的新对象

List<object>[] addedLists = New.Keys.Except(Existing.Keys)
                                    .Select(key => New[key])
                                    .ToArray();
object[] addedObjects = Existing.Keys.Intersect(New.Keys)
                                     .SelectMany(key => New[key].Except(Existing[key])
                                     .ToArray();

但最后一项要求有点不明确。您将如何定义更改后的对象?哪些对象应该进行比较以进行更改?将任何对象与任何其他对象进行比较都可能被定义为不同,因此必须有一些相似性作为比较的基础(例如,ID属性中具有相同值的对象(。

编辑:正如您在评论中阐明的对象标识是如何定义的,以下是如何查找所有更改的对象(假设字典的值是具有属性NameTypeFoo的列表,这些属性标识了对象和可能更改的属性Value

var differences = Existing.Keys.Intersect(New.Keys).SelectMany(key =>
    from existingObj in Existing[key]
    join newObj in New[key] on new { existingObj.Name, existingObj.Type } equals
                               new { newObj.Name, newObj.Type }
    where existingObj.Value != newObj.Value
    select new { Key = key, Existing = existingObj, New = newObj });

这将产生一系列对象,每个对象都包含差异所在字典的关键字、现有对象和新对象。相同的对象将不会包含在结果中。

Dictionary<string, int> New = new Dictionary<string, int>();
Dictionary<string, int> Existing = new Dictionary<string, int>();
New.Add("A", 100);
New.Add("B", 200);
New.Add("Y", 300);
New.Add("X", 400);

Existing.Add("A", 1);
Existing.Add("B", 2);
Existing.Add("C", 3);
Existing.Add("D", 4);
Existing.Add("E", 5);
Existing.Add("F", 6);
Existing.Add("G", 7);
Existing.Add("H", 8);
var newStuff = New.Where(n => !Existing.ContainsKey(n.Key)).ToList();
var updatedStuff = Existing.Where(e => New.ContainsKey(e.Key) && e.Value != New.Single(n => n.Key == e.Key).Value);

newStuff.Dump();
updatedStuff.Dump();
//updated and new 
newStuff.AddRange(updatedStuff);
newStuff.Dump();

在Linqpad完成。