如何使用LINQ按ID去重并对指定属性(如Price)求和?
高效LINQ实现:按ID去重并求和指定属性
嘿,这个需求我经常碰到,给你分享两种高效的实现思路,既能按ID去除列表重复项,又能把对应Price属性求和,完全匹配你的示例要求~
首先先确认一下Item类的定义(方便后续代码运行):
public class Item { public int Id { get; set; } public string Name { get; set; } public string Code { get; set; } public decimal Price { get; set; } }
方法一:LINQ GroupBy + Select(推荐,可读性+效率兼顾)
这是最直观且高效的LINQ写法,GroupBy内部基于哈希表实现,时间复杂度是O(n),完全能应对大部分业务场景:
var originalList = new List<Item> { new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} }; var result = originalList // 按Id分组,把相同Id的项归为一组 .GroupBy(item => item.Id) // 对每个分组转换为目标Item .Select(group => new Item { Id = group.Key, // 取分组中第一个项的Name和Code(和你的期望结果一致) Name = group.First().Name, Code = group.First().Code, // 对分组内的Price求和 Price = group.Sum(item => item.Price) }) .ToList();
为什么这个方法高效?
GroupBy会一次性遍历原列表,用哈希表快速分组;后续Select只需要遍历分组后的结果(数量远小于原列表),整体是线性时间复杂度,性能非常出色,同时代码可读性拉满,团队里的其他同事一眼就能看懂逻辑。
方法二:手动使用Dictionary(极端大列表场景可选)
如果你的列表数据量特别大(比如百万级以上),可以考虑手动用Dictionary实现,减少LINQ的封装开销,性能会略优于GroupBy(差异其实不大,但极端场景下能体现):
var originalList = new List<Item> { // 同上的初始化代码 }; var idItemMap = new Dictionary<int, Item>(); foreach (var item in originalList) { if (idItemMap.TryGetValue(item.Id, out var existingItem)) { // 已存在相同Id的项,累加Price existingItem.Price += item.Price; } else { // 不存在则添加新项(注意创建新对象,避免修改原列表的元素) idItemMap.Add(item.Id, new Item { Id = item.Id, Name = item.Name, Code = item.Code, Price = item.Price }); } } var result = idItemMap.Values.ToList();
注意点
这个方法同样是O(n)时间复杂度,和GroupBy的底层逻辑类似,但手动实现少了LINQ的一些抽象层,在超大数据量下会有微小的性能优势。不过缺点是代码比LINQ写法冗长,可读性稍差,所以如果不是性能敏感场景,更推荐第一种方法。
结果验证
两种方法最终都会得到你期望的结果列表:
List<Item> result = new List<Item> { new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 200}, new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 550} };
内容的提问来源于stack exchange,提问作者djedjica
相关产品推荐
相关产品推荐

