如何将不在baseList中的relatedItems添加至relatedList?
我来帮你搞定这个问题!你之前的写法有几个关键错误,导致没法实现预期功能,我一步步给你捋清楚:
问题出在哪?
- AddRange没有返回值:
AddRange是个void方法,调用后不会返回集合,所以你不能在它后面链式调用Except,这会直接编译报错。 - Except的用法错了:
Except的参数得是一个集合,不是lambda表达式(你写的x => x in baseList不符合语法)。它的作用是返回两个集合的差集——也就是在第一个集合里但不在第二个集合里的元素。 - 相等判断逻辑不明确:如果你的元素是自定义类,默认的
Except会用引用相等(引用类型)或值相等(值类型)来判断;要是你想根据id判断,得明确指定判断逻辑。
正确的写法
场景1:根据元素整体相等判断(值类型或重写了Equals的自定义类)
每次获取相关项后,先通过Except过滤掉baseList里已有的元素,再添加到relatedList:
foreach (var baseItem in baseList) { // 获取当前baseItem对应的相关项 var relatedItems = GetRelatedItems(baseItem); // 过滤掉baseList中已存在的元素 var itemsToAdd = relatedItems.Except(baseList); // 把过滤后的元素添加到目标列表 relatedList.AddRange(itemsToAdd); }
场景2:根据id属性判断相等(自定义类,不想重写Equals)
如果你的元素是自定义类,且只想通过id判断是否存在,用Where+Any会更直观:
foreach (var baseItem in baseList) { var relatedItems = GetRelatedItems(baseItem); // 只保留那些id不在baseList中的元素 var itemsToAdd = relatedItems.Where(x => !baseList.Any(b => b.id == x.id)); relatedList.AddRange(itemsToAdd); }
额外优化提示
要是baseList比较大,担心Any的性能问题,可以先把baseList的id存入HashSet,这样判断元素是否存在的速度会快很多:
// 提前把baseList的id存入HashSet,提升查询效率 var baseIds = new HashSet<int>(baseList.Select(b => b.id)); foreach (var baseItem in baseList) { var relatedItems = GetRelatedItems(baseItem); var itemsToAdd = relatedItems.Where(x => !baseIds.Contains(x.id)); relatedList.AddRange(itemsToAdd); }
内容的提问来源于stack exchange,提问作者user1283776
相关产品推荐
相关产品推荐

