繁体   English   中英

C#/ .NET比较两个大列表并从两个列表中查找缺失的项

[英]C# / .NET comparing two large lists and finding missing items from both list

所以基本上我有两个大列表,如下所示:

public class Items
{
 public string ItemID { get; set; }
}


var oldList = new List<Items>(); // oldList

var newList = new List<Items>(); // new list

两个列表都非常大,并且如果两个列表都很大(超过30秒),则由于执行时间较差,因此简单的double foreach就不够了。

在我对stackoverflow提出的上一个问题中,我得到了一个答复,该答复是如何比较这两个相同的列表并找出哪些项目具有不同的QuantitySold参数,然后将其存储在名为“ DifferentQuantityItems”的第三个列表中,如下所示:

var differentQuantityItems =
    (from newItem in newList
     join oldItem in oldList on newItem.ItemID equals oldItem.ItemID
     where newItem.QuantitySold != oldItem.QuantitySold
     select newItem).ToList();

现在,我想从这两个列表中获取以下信息:

- A list of items that are present in newList, but not in oldList

- A list of items that are present in oldList, but not in newList

我该如何实现? 有人可以帮我吗?

PS我通过列表属性“ ItemID”“知道”列表中的任何一个缺失的方法...

您是否考虑过将列表转换为哈希集并使用Except方法?

请参阅两个列表之间的差异

并且: 有没有一种方法可以在c#中获得两组对象之间的差异

var items = new List<int>(oldList.Select(x => x.ItemID ));
var missingValues = newList.Where(x => !diffids.Contains(x.ItemID)).ToList();

您也可以使用除外。

编辑

除了会更快地工作。 在这里你可以读到它的性能

var missedOld = oldList.Except(newList, new ItemsEqualityComparer());
var oldList= oldList.Except(missedOld, new ItemsEqualityComparer());

旧答案

缺少项目的两个不同列表

var missedOld = oldList.Where(x => !newList.Select(i => i.ItemID).Contains(x.ItemID)) 
var missedNew = newList.Where(x => !oldList.Select(i => i.ItemID).Contains(x.ItemID))

一个列表中所有未填写的项目:

oldList.Concat(newList).GroupBy(x => x.ItemID).Where(x => x.Count() < 2).Select(x => x.Value).ToList()

如果列表足够大,以至于嵌套循环需要30秒,那么我建议您将每个列表的项目放入各自的HashSet中,并使用它来查找异常。 哈希表将按O(1)或O(log N)缩放,而比较2个未排序的列表为O(n ^ 2)。

就是说,尝试使用Linq Except()

var notinNewList = oldList.Except(newList);

如果我没记错的话,.Except()的内部实现依赖于HashSets

其次,如果列表已排序,或者可以进行预排序,则可以一口气进行线性传递而没有嵌套循环,这可能比任何方法都要快。

我不建议使用List.Contains(),因为它是一个线性实现,这将导致您尝试避免相同的O(n ^ 2),尽管由于Linq语法糖,它看起来更漂亮。

var items = newList.Where(n => !oldlist.Any(o => o.ItemID == n.ItemID)).ToList();

它更加敏捷,因为您无需再次进入DB且无需使用Contains,就像在SQL中一样,它也位于一行中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM