使用Where子句筛选IEnumerable列表唯一ID元素的代码问题
问题分析与解决方案
嗨,我来帮你捋清楚这个Linq代码的问题哈~
首先看你写的这段代码:
IEnumerable<Boat> newBoats = updatedBoats.Where(c => oldBoats.Any(d => d.GetId() != c.GetId())).ToList();
为什么当两个列表ID都是[1,2,3,4,5]时,代码没按预期工作?因为你的判断逻辑搞反啦!Any(d => d.GetId() != c.GetId())的意思是:只要oldBoats里有任意一个ID不等于当前元素的ID,就把这个元素留下来。那对于任何一个元素来说,oldBoats里肯定有其他不同的ID(比如ID=1的元素,oldBoats里有2、3这些),所以所有元素都会被误判成“新元素”,这就完全不符合你的需求了。
正确的写法
你要的是找出updatedBoats里ID不在oldBoats里的元素,所以应该反过来判断:检查oldBoats里有没有和当前元素ID相同的,如果没有,就保留它。代码如下:
// 基础实现 IEnumerable<Boat> newBoats = updatedBoats .Where(c => !oldBoats.Any(d => d.GetId() == c.GetId())) .ToList();
更高效的优化方案
如果你的列表数据量比较大,上面的代码每次判断都要遍历整个oldBoats,效率会很低。咱们可以先把oldBoats的ID提取到一个HashSet里,HashSet的查找是O(1)的,性能会提升很多:
// 高性能版本,适合大数据量场景 var oldBoatIds = new HashSet<int>(oldBoats.Select(boat => boat.GetId())); IEnumerable<Boat> newBoats = updatedBoats .Where(boat => !oldBoatIds.Contains(boat.GetId())) .ToList();
这样既解决了逻辑错误,又兼顾了性能,完美符合你的需求~
内容的提问来源于stack exchange,提问作者lost9123193
相关产品推荐
相关产品推荐

