平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“.NET 中实现方法 List 集合去重的做法”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
前言
落到代码里,在数据处理里,去除集合中的重复元素是一个常用的需求。.NET 6 和 .NET 7 引入了 DistinctBy 方法,这是一个很实用的新特性,能够便于地根据指定的键对集合进行去重。
下面会系统梳理 DistinctBy 方法的采用,并借助具体的案例来展示其在真实项目中的应用。
正文
1、DistinctBy 方法
DistinctBy 方法允许我们在 LINQ 查询中根据某个键对集合中的元素进行去重。
这个方法得到一个新的集合,其中只包含根据指定键唯一确定的元素。
方法签名
public static IEnumerableDistinctBy (
this IEnumerablesource,
FunckeySelector
);
2、基本用法
落到代码里,最轻松的用法是在 LINQ 查询中直接调用 DistinctBy 方法,随后处理去重后的集合。
说明
假设我们有一个用户列表,我们想要根据用户名去除重复的用户。
using System.Linq;
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
var users = new List
{
new User { Name = "Alice", Age = 25 },
new User { Name = "Bob", Age = 32 },
new User { Name = "Alice", Age = 28 },
new User { Name = "David", Age = 35 }
};
var distinctUsers = users.DistinctBy(user => user.Name);
foreach (var user in distinctUsers)
{
Console.WriteLine($"Name: {user.Name}, Age: {user.Age}");
}
输出结果:
Name: Alice, Age: 25
Name: Bob, Age: 32
Name: David, Age: 35
过滤前后元素还是保持原有的顺序,我们能够查看源码。
源码
private static IEnumerableDistinctByIterator (IEnumerable source, Func keySelector, IEqualityComparer ? comparer)
{
using IEnumeratorenumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
var set = new HashSet(DefaultInternalSetCapacity, comparer);
do
{
TSource element = enumerator.Current;
if (set.Add(keySelector(element)))
{
yield return element;
}
}
while (enumerator.MoveNext());
}
}
在这个场景下,借助查看源码,能够看到是借助了 HashSet 去重,元素顺序同时未被打乱。
在处理集合时,我们经常需去除重复的元素,同时保持原有的顺序。
采用 HashSet 能够高效地实现这一目标。
首先将指定的键尝试添加到 HashSet 中,如果添加成功,说明该键没有重复;
若添加失败,说明已经存在相同的键,此元素将被过滤掉。
3、复杂用法
DistinctBy 方法能够用来更复杂的去重逻辑,比如根据多个属性进行去重。
说明
假设我们有一个订单列表,我们想要根据客户名称和订单金额去除重复的订单。
class Order
{
public int OrderId { get; set; }
public string CustomerName { get; set; }
public decimal Amount { get; set; }
}
var orders = new List
{
new Order { OrderId = 1, CustomerName = "Alice", Amount = 100.0m },
new Order { OrderId = 2, CustomerName = "Bob", Amount = 150.0m },
new Order { OrderId = 3, CustomerName = "Alice", Amount = 100.0m },
new Order { OrderId = 4, CustomerName = "Charlie", Amount = 120.0m },
new Order { OrderId = 5, CustomerName = "Bob", Amount = 150.0m }
};
var distinctOrders = orders.DistinctBy(order => (order.CustomerName, order.Amount));
foreach (var order in distinctOrders)
{
Console.WriteLine($"Order ID: {order.OrderId}, Customer: {order.CustomerName}, Amount: {order.Amount}");
}
输出结果:
Order ID: 1, Customer: Alice, Amount: 100.0
Order ID: 2, Customer: Bob, Amount: 150.0
Order ID: 4, Customer: Charlie, Amount: 120.0
4、性能考虑
DistinctBy 方法在内部采用哈希表来跟踪已经出现的键,所以在大多数情况下性能很好。但在处理很大的数据集时,仍然需留意内存采用情况。
说明
假设我们有一个包含数百万条记录的大集合,我们需根据某个键进行去重。
var largeCollection = Enumerable.Range(1, 10000000).Select(i => new { Id = i, Value = i % 1000 });
var distinctLargeCollection = largeCollection.DistinctBy(item => item.Value);
Console.WriteLine($"Distinct count: {distinctLargeCollection.Count()}");5、异步 LINQ 查询中的采用
DistinctBy 方法也能够在异步 LINQ 查询中采用,结合 IAsyncEnumerable 类型,处理大量数据时更加高效。
说明
在这个场景下,假设我们有一个异步方法得到一个用户列表,我们想要根据用户名去除重复的用户。
using System.Net.Http.Json
public async IAsyncEnumerableGetUsersAsync()
{
var response = await httpClient.GetAsync("https://api.example.com/users");
var usersJson = await response.Content.ReadAsStringAsync();
// 使用Json序列化工具解析用户列表
var users = JsonSerializer.Deserialize>(usersJson);
foreach (var user in users)
{
yield return user;
}
}
// 使用异步LINQ查询
var distinctUsers = await GetUsersAsync().DistinctByAsync(user => user.Name).ToListAsync();
foreach (var user in distinctUsers)
{
Console.WriteLine($"Name: {user.Name}, Age: {user.Age}");
}
总结
DistinctBy 方法是 .NET 6 和 .NET 7 中 LINQ 的一个很实用的新特性。我们在 LINQ 查询中根据指定的键对集合进行去重,简化了代码同时提高了开发效率。
理解这一步时,希望本文能帮助大家更好地理解和借助 .NET 6 和 .NET 7 中 LINQ 的 DistinctBy 方法,从而在项目里发挥更大的作用。
到此这篇关于.NET 中更快实现 List 集合去重的文章就介绍到这了,更多相关.net list集合去重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!
- ASP.NET中 ListBox列表框控件的采用方法
- asp.net拿到ListView与gridview中当前行的行号
- .NET中求复杂类型集合的差集、交集、并集
- .Net中的集合排序能够这么玩你知道吗
- 分享下Asp.Net面试题目及答案集合
- 关于.NET的集合总结
- asp.net DataTable相关操作集锦(筛选,取前N条数据,去重复行,拿到指定列数据等)
