从列表中删除子列表 [英] Remove sublist from a list

查看:177
本文介绍了从列表中删除子列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有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.

这篇关于从列表中删除子列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆