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

C# C/.NET比较两个大列表并从两个列表中查找缺少的项,c#,linq,C#,Linq,因此,基本上我有两个大列表,如下所示: public class Items { public string ItemID { get; set; } } var oldList = new List<Items>(); // oldList var newList = new List<Items>(); // new list var differentQuantityItems = (from newItem in newList joi

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

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


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

var newList = new List<Items>(); // new list
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
我怎样才能做到这一点?有人能帮我吗


另外,我知道其中一个列表缺少任何一项的方法是通过属性ItemID…

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

以及:

您也可以使用除外。

编辑

但它的工作速度要快得多。你可以读到它的性能

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

它更灵活,因为您不需要再次转到DB,也不需要使用Contains,它类似于SQL中的like,也在一行中。

如果列表足够大,嵌套循环需要30秒,我建议您将每个列表的项放入相应的哈希集中,并使用该哈希集查找异常。哈希表将按O1或Olog N缩放,而比较2个未排序的列表则在^2上

也就是说,尝试使用Linq

var notinNewList = oldList.Except(newList);
如果我没有弄错的话,.Except的内部实现依赖于哈希集

其次,如果列表已排序,或者可以预先排序,那么您可以在不使用嵌套循环的情况下进行一次一次线性传递,这可能比任何方法都快


我不建议使用List.Contains,因为它是一个线性实现,这将导致^2上出现与您试图避免的相同的结果,尽管由于Linq语法的特殊性,它看起来更漂亮。

有人吗=您可以尝试LINQ的交集和并集您可以使用Equals方法和自定义比较器类使用LINQ不会保证任何性能提高,请看这里@Aarif-ouh当我看到一个回复中提到的并行循环时,我立即跑掉了。。。我对并行循环有不好的体验,这一个让我有点困惑。。。我可以以类的形式提取项目吗?不仅仅是整数值..:好的,如果可能的话,你能给我举个例子吗同意尝试例外,因为它应该是O1或Olog N复杂度,因为内部使用HashSet,虽然我不是100%,但在测试中,似乎你不应该创建一个新变量并将新值存储在其中吗?顺便说一下,我希望将两个列表中缺少的项分隔在两个不同的列表中=d@User987是的,当然您应该将这个表达式的值放入新变量中并使用它,而不是从旧列表或新列表中获取缺少的项:D@User987您也可以通过这样的属性进行比较:var missedOld=oldList.Wherex=>!newList.Selectl=>l.ItemID.Containsx.ItemID
var items = newList.Where(n => !oldlist.Any(o => o.ItemID == n.ItemID)).ToList();
var notinNewList = oldList.Except(newList);