[英]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”“知道”列表中的任何一个缺失的方法...
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.