首页 / C#开发 / 正文

C#/.NET应用程序编程开发中如何从一个集合List<T>中删除在另一个集合List<T>中的所有元素?

3981 1 发布于: 2019-06-04 读完约需16分钟

问题描述

在C#/.NET应用程序编程开发中,如何从一个集合List<T>中删除在另一个集合List<T>中的所有元素?

现在有一个业务场景为:某系统有一个客户表,其中存储着所有客户的数据,现在需要从这个客户表中提取符合条件的客户列表,并发送促销邮件,这里的条件为排除退订的客户。

假设我们把所有客户集合命名为allCustomers,将需要排除的客户集合命名为exceptCustomers

这里假设是用C#程序来作数据筛选,请暂时忘掉数据库的条件筛选功能,OK?

客户类Customer.cs:

public class Customer
{
  public int Id{get;set;}
  public string Name{get;set;}
}

所有客户集合allCustomers:

var allCustomers = new List<Customer>
{
    new Customer { Id = 1, Name = "Customer 1"},
    new Customer { Id = 2, Name = "Customer 2"},
    new Customer { Id = 3, Name = "Customer 3"},
    new Customer { Id = 4, Name = "Customer 4"},
    new Customer { Id = 5, Name = "Customer 5"}
};

需要排除的客户集合exceptCustomers:

var exceptCustomers = new List<Customer>
{
    new Customer { Id = 1, Name = "Customer 1"},
    new Customer { Id = 3, Name = "Customer 3"}
};

排除后的结果应该是allCustomers集合中只剩下用户ID为:2,4,5

方案一

如果是对象集合,则使用LINQ的Where()Any()扩展方法筛选,完整的测试代码如下(你可以复制以下代码,然后在https://try.dot.net/运行):

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  public static void Main()
  {
    DoWork();
  }

  private static void DoWork()
  {
    var allCustomers = new List<Customer>
    {
      new Customer { Id = 1, Name = "Customer 1"},
      new Customer { Id = 2, Name = "Customer 2"},
      new Customer { Id = 3, Name = "Customer 3"},
      new Customer { Id = 4, Name = "Customer 4"},
      new Customer { Id = 5, Name = "Customer 5"}
    };

    var exceptCustomers = new List<Customer>
    {
      new Customer { Id = 2, Name = "Customer 2"},
      new Customer { Id = 4, Name = "Customer 4"}
    };

    var result = allCustomers.Where(x=>!exceptCustomers.Any(e=>e.Id==x.Id)).ToList();

    foreach(var customer in result){
      Console.WriteLine($"Customer id:{customer.Id}");
    }
  }
}

public class Customer
{
  public int Id{get;set;}
  public string Name{get;set;}
}

输出结果为:
Customer id:1
Customer id:3
Customer id:5

方案二

我们知道,LINQ还有一个扩展方法为Except(),它是用作从一个集合中排除另一个集合的。在上面的示例中,如果你直接使用Except()方法是行不通的,这时的Customer类要继承IEquatable接口并实现Equals()方法,如下:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  public static void Main()
  {
    DoWork();
  }

  private static void DoWork()
  {
    var allCustomers = new List<Customer>
    {
      new Customer { Id = 1, Name = "Customer 1"},
      new Customer { Id = 2, Name = "Customer 2"},
      new Customer { Id = 3, Name = "Customer 3"},
      new Customer { Id = 4, Name = "Customer 4"},
      new Customer { Id = 5, Name = "Customer 5"}
    };

    var exceptCustomers = new List<Customer>
    {
      new Customer { Id = 2, Name = "Customer 2"},
      new Customer { Id = 4, Name = "Customer 4"}
    };

    var result = allCustomers.Except(exceptCustomers).ToList();

    foreach(var customer in result){
      Console.WriteLine($"Customer id:{customer.Id}");
    }
  }
}

public class Customer : IEquatable<Customer>
{
  public int Id{get;set;}
  public string Name{get;set;}

  public bool Equals(Customer other)
  {
      if (other is null)
          return false;

      return this.Id == other.Id;
  }

  public override bool Equals(object obj) => Equals(obj as Customer);
  public override int GetHashCode() => (Id, Name).GetHashCode();
}

输出结果为:
Customer id:1
Customer id:3
Customer id:5

方案三

如果两个集合为简单数据类型集合,如:

var allCustomers = new List<int>{1,2,3,4,5,6};
var exceptCustomers = new List<int>{1,3,5};

这时,我们可以使用LINQ的Except()扩展方法,如下:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  public static void Main()
  {
    DoWork();
  }

  private static void DoWork()
  {
    var allCustomers = new List<int>{1,2,3,4,5,6};
    var exceptCustomers = new List<int>{1,3,5};
    var result = allCustomers.Except(exceptCustomers);
    foreach(var customer in result){
      Console.WriteLine($"Customer id:{customer}");
    }
  }
}

输出结果为:
Customer id:2
Customer id:4
Customer id:6

方案四

最传统的循环的方式,使用LINQ的Remove()方法,如下:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  public static void Main()
  {
    DoWork();
  }

  private static void DoWork()
  {
    var allCustomers = new List<Customer>
    {
      new Customer { Id = 1, Name = "Customer 1"},
      new Customer { Id = 2, Name = "Customer 2"},
      new Customer { Id = 3, Name = "Customer 3"},
      new Customer { Id = 4, Name = "Customer 4"},
      new Customer { Id = 5, Name = "Customer 5"}
    };

    var exceptCustomers = new List<Customer>
    {
      new Customer { Id = 2, Name = "Customer 2"},
      new Customer { Id = 4, Name = "Customer 4"}
    };

    foreach(var c in exceptCustomers){
      foreach(var cus in allCustomers){
        if(c.Id == cus.Id){
          allCustomers.Remove(cus);
          break;
        }
      }
    }

    foreach(var customer in allCustomers){
      Console.WriteLine($"Customer id:{customer.Id}");
    }
  }
}

public class Customer : IEquatable<Customer>
{
  public int Id{get;set;}
  public string Name{get;set;}

  public bool Equals(Customer other)
  {
      if (other is null)
          return false;

      return this.Id == other.Id;
  }

  public override bool Equals(object obj) => Equals(obj as Customer);
  public override int GetHashCode() => (Id, Name).GetHashCode();
}

输出结果为:
Customer id:1
Customer id:3
Customer id:5

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: C#/.NET应用程序编程开发中如何实现不使用InstallUtil.exe安装Windows服务(Windows Service)?

下一篇: C#/.NET WPF应用程序编程开发中如何获取当前程序所有目录的路径?

本文永久链接码友网 » C#/.NET应用程序编程开发中如何从一个集合List<T>中删除在另一个集合List<T>中的所有元素?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册