为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
一只名叫tom的猫 2022-10-23 10:11:44
所以基本上我有两个大列表,如下所示:public class Items{ public string ItemID { get; set; }}var oldList = new List<Items>(); // oldListvar newList = new List<Items>(); // new list两个列表都非常大,如果它们都很大(超过 30 秒),由于执行时间很短,因此简单的双 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”......
查看完整描述

4 回答

?
米脂

TA贡献1836条经验 获得超3个赞

已编辑


除了会工作得更快。在这里您可以了解它的性能


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()



查看完整回答
反对 回复 2022-10-23
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

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

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

并且:有没有办法在c#中获得两组对象之间的差异


查看完整回答
反对 回复 2022-10-23
?
Qyouu

TA贡献1786条经验 获得超11个赞

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

您也可以使用除。


查看完整回答
反对 回复 2022-10-23
?
九州编程

TA贡献1785条经验 获得超4个赞

如果列表足够大以至于嵌套循环需要 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 语法糖它看起来更漂亮。


查看完整回答
反对 回复 2022-10-23
  • 4 回答
  • 0 关注
  • 128 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信