最快的方法来比较两个List <>

什么是比较两个大型(> 50.000项)最快(也是最less的资源密集型),结果有两个列表如下:

  1. 在第一个列表中出现但不在第二个列表中的项目
  2. 在第二个列表中显示但不在第一个列表中的项目

目前我正在使用列表或IReadOnlyCollection并在linq查询中解决此问题:

var list1 = list.Where(i => !list2.Contains(i)).ToList(); var list2 = list2.Where(i => !list.Contains(i)).ToList(); 

但是这并不如我所愿。 任何想法使这个更快,更less的资源密集型,因为我需要处理大量的名单?

使用Except

 var firstNotSecond = list1.Except(list2).ToList(); var secondNotFirst = list2.Except(list1).ToList(); 

我怀疑有些方法实际上比这更快,但即使这样也会比O(N * M)方法快得多。

如果你想结合这些,你可以用上面的方法创build一个方法,然后返回一个声明:

 return !firstNotSecond.Any() && !secondNotFirst.Any(); 

更高效的将使用Enumerable.Except

 var inListButNotInList2 = list.Except(list2); var inList2ButNotInList = list2.Except(list); 

这个方法是通过使用延迟执行来实现的。 这意味着你可以写例如:

 var first10 = inListButNotInList2.Take(10); 

这也是有效的,因为它在内部使用Set<T>来比较对象。 它的工作原理是首先收集第二个序列中的所有不同值,然后stream式传输第一个的结果,检查之前没有看到它们。

如果您希望结果不区分大小写 ,则以下内容将起作用:

 List<string> list1 = new List<string> { "a.dll", "b1.dll" }; List<string> list2 = new List<string> { "A.dll", "b2.dll" }; var firstNotSecond = list1.Except(list2, StringComparer.OrdinalIgnoreCase).ToList(); var secondNotFirst = list2.Except(list1, StringComparer.OrdinalIgnoreCase).ToList(); 

firstNotSecond将包含b1.dll

secondNotFirst将包含b2.dll

不是为这个问题,但这里有一些代码来比较列表的平等和不! 相同的对象:

 public class EquatableList<T> : List<T>, IEquatable<EquatableList<T>> where T : IEquatable<T> /// <summary> /// True, if this contains element with equal property-values /// </summary> /// <param name="element">element of Type T</param> /// <returns>True, if this contains element</returns> public new Boolean Contains(T element) { return this.Any(t => t.Equals(element)); } /// <summary> /// True, if list is equal to this /// </summary> /// <param name="list">list</param> /// <returns>True, if instance equals list</returns> public Boolean Equals(EquatableList<T> list) { if (list == null) return false; return this.All(list.Contains) && list.All(this.Contains); } 

试试这个方法:

 var difList = list1.Where(a => !list2.Any(a1 => a1.id == a.id)) .Union(list2.Where(a => !list1.Any(a1 => a1.id == a.id))); 

我用这个代码来比较两个拥有百万条logging的列表。

这种方法不会花费太多时间

  //Method to compare two list of string private List<string> Contains(List<string> list1, List<string> list2) { List<string> result = new List<string>(); result.AddRange(list1.Except(list2, StringComparer.OrdinalIgnoreCase)); result.AddRange(list2.Except(list1, StringComparer.OrdinalIgnoreCase)); return result; } 

可能是它的有趣,但为我工作

string.Join(“”,List1)!= string.Join(“”,List2)