问题描述
在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
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册