c# - 从列表中删除子列表

标签 c# .net

我有 2 个列表:list1list2(均为 int 类型)

现在我想从 list1 中删除 list2 的内容。我如何在 C# 中执行此操作?

PS:不要使用循环。

最佳答案

重要变化

正如评论中指出的那样,.Except()在内部使用集合,因此 list1 的任何重复成员将不会出现在最终结果中。

Produces the set difference of two sequences

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.except(v=vs.110).aspx

但是,有一个解决方案既是 O(N) 又保留了原始列表中的重复项:修改 RemoveAll(i => list2.Contains(i))使用 HashSet<int> 的方法保留排除集。

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 的解决方案进行了简单的基准测试。

对于 list2只有一个元素,他的代码更快。作为list2变得越来越大,他的代码变得极度慢。看起来他的是 O(N-squared)(或更具体地说是 O(list1.length*list2.length) 因为将 list1 中的每个项目与 list2 中的每个项目进行比较)。没有足够的数据点来检查我的解决方案的 Big-O,但当 list2 时速度要快得多有很多元素。

用于测试的代码:

        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 以外的所有尺寸.如果没有其他引用必须看到更新,出于这个原因,这是更可取的。

关于c# - 从列表中删除子列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14388834/

相关文章:

c# - C# WinMobile 6.1 项目中的 C++ DLL - 1c2 机器 (Thumb) 与 14c 机器 (x86)

c# - LINQpad 线程行为

c# - ServiceStack 3.9.71 中缺少类型

.net - 使用按钮转到另一个窗口窗体

c# - 如何使用 C# 以编程方式从 Word 文档中删除一行?

.net - Entity Framework 可以在控制台程序中运行,但不能在azure函数中运行

.net - 了解 Windows 中的 AppDomain

c# - 在我的应用程序中更改事件选项卡的快捷方式

c# - 如何在 .net 中为网络适配器设置 dns 搜索后缀?

c# - 如何在 WPF 中进行 CPU 使用控制