C#比较两个不同对象的列表

我看到了比较两个List 的最快方法,但是我无法适应我的情况。 我的问题是列表是不同类型的。

我的清单是这样的:

List firstList; List secondList; 

这就是我现在拥有的:

 foreach (Type1 item in firstList) { if (!secondList.Any(x => x.Id == item.Id)) { // this code is executed on each item in firstList but not in secondList } } foreach (Type2 item in secondList) { if (!firstList.Any(x => x.Id == item.Id)) { // this code is executed on each item in secondList but not in firstList } } 

这适用于所有,但是是O(n^2) 。 有没有办法让这个更有效率? 我在上面链接的问题中的解决方案说使用.Except除了它不需要lambda。

编辑:我在上面提到过,但这仍然被标记为重复。 我没有两个相同对象的列表。 我有两个不同对象的列表。 Type1和Type2是不同的类型。 他们都有一个我需要匹配的ID。

我建议将2种类型的ID转换为2种HashSets。 然后你可以

 HashSet a = new HashSet(firstList.Select(o => o.Id)); HashSet b = new HashSet(secondList.Select(o => o.Id)); if (a.IsSubsetOf(b) && b.IsSubsetOf(a)) { //Do your thing } 

我不确定可用的C#/ Linq方法。 从算法的角度来看,您可以对两个列表进行排序(通常为O(n*log(n)) )。 然后你只需要扫描列表(线性,又名O(m+n) ,其中m是列表1中元素的数量, n是列表2中元素的数量)。 假设列表1是较长的列表,则总复杂度为O(m*log(m)) 。 根据C#HashSet的实现,Murdock的答案可能会更快。

Except -method有一个重载,它将IEqualityComparer作为最后一个参数。

MSDN中有一个示例: https : //msdn.microsoft.com/en-us/library/bb336390.aspx

编辑
可以创建匿名对象列表,并将它们与特殊的IEqualityComparer 。 这是比较器类:

 class MyEqualityComparer : IEqualityComparer { #region IEqualityComparer Members bool IEqualityComparer.Equals(object x, object y) { return (x as dynamic).Id == (y as dynamic).Id; } int IEqualityComparer.GetHashCode(object obj) { return ((obj as dynamic).Id as object).GetHashCode(); } #endregion } 

LINQ表达式应如下所示:

 var result = lst1.Select(x => new { Id = x.Id, Obj = x }) .Except(lst2.Select(x => new { Id = x.Id, Obj = x }), new MyEqualityComparer()) .Select(x => (x as dynamic).Obj as Type1); 

我知道,在这种情况下使用动态是一种糟糕的风格,你可以毫无问题地将其改为实际类型。