我有2列出:的List1
和 list2中
(包括int型)
I have 2 lists: list1
and list2
(both of type int)
现在我想从的List1
清除 list2中
的内容。我如何在C#中做到这一点?
Now I want to remove content of list2
from list1
. How I can do this in C#?
PS:不要使用循环
重要的变化
正如有人指出,在评论中,。除()
使用了一组内部,所以的List1 将不存在于最终的结果。
As was pointed out in the comments, .Except()
uses a set internally, so any duplicate members of list1
will be absent in the final result.
生成的设置两个序列的差异
的http://msdn.microsoft.com/en-us/library/system.linq.enumerable.except(v=vs.110).aspx
不过,有一个解决方案,既O(N)和$ P原始列表$ pserves重复:修改 removeall过(I => list2.Contains(I))
办法使用的HashSet< INT>
持有的排除设置
However, there is a solution that is both O(N) and preserves duplicates in the original list: Modify the RemoveAll(i => list2.Contains(i))
approach to use a HashSet<int>
to hold the exclusion set.
List<int> list1 = Enumerable.Range(1, 10000000).ToList();
HashSet<int> exclusionSet = Enumerable.Range(500000, 10).ToHashSet();
list1.Remove(i => exclusionSet.Contains(i));
扩展方法 ToHashSet()
中的 MoreLinq 。
原来的答案
您可以使用LINQ
list1 = list1.Except(list2).ToList();
更新
出于好奇,我做了我的解决方案的一个简单的基准与@ HighCore的。
Out of curiosity I did a simple benchmark of my solution vs. @HighCore's.
有关 list2中
有只有一个元素,他的code是速度更快。由于 list2中
变得越来越大,他的code得到的非常的慢。它看起来像他的就是 O(N平方)(或更具体地说O(list1.length * list2.length)因为的List1
每个项目相比于每个项目 list2中
)。没有足够的数据点,检查大啊,我的解决方案,但它的速度要快得多,当 list2中
比少数元素更多。
For list2
having just one element, his code is faster. As list2
gets larger and larger, his code gets extremely slow. It looks like his is O(N-squared) (or more specifically O(list1.length*list2.length) since each item in list1
is compared to each item in list2
). Don't have enough data points to check the Big-O of my solution, but it is much faster when list2
has more than a handful of elements.
用于测试code:
List<int> list1 = Enumerable.Range(1, 10000000).ToList();
List<int> list2 = Enumerable.Range(500000, 10).ToList(); // Gets MUCH slower as 10 increases to 100 or 1000
Stopwatch sw = Stopwatch.StartNew();
//list1 = list1.Except(list2).ToList();
list1.RemoveAll(i => list2.Contains(i));
sw.Stop();
var ms1 = sw.ElapsedMilliseconds;
更新2
此解决方案分配一个新的列表变量的List1
。正如@Толя指出,其他参考资料(如果有的话),以原始的的List1
将不会被更新。该解决方案大大优于 removeall过
为所有,但 list2中
的最小尺寸。如果没有其他引用必须看到更新,它是preferable出于这个原因。
This solution assigns a new list to the variable list1
. As @Толя points out, other references (if any) to the original list1
will not be updated. This solution drastically outperforms RemoveAll
for all but the smallest sizes of list2
. If no other references must see the update, it is preferable for that reason.