C#中foreach列表对比无法返回唯一值问题求助
问题分析
原代码核心问题是嵌套循环导致重复添加元素:外层遍历6个视口时,每次内层都会遍历所有视图,把符合条件的视图反复加入vNoSheet,同一个视图会被添加多次(比如预期的19个视图,每个被重复添加6次,19×6=114,再加上少量重复元素就接近120了)。另外vList的填充逻辑完全错误,每次循环都重复添加视图,根本起不到“列表2”的作用。
修改方案
用LINQ集合操作简化逻辑,避免嵌套循环的重复操作,直接得到唯一元素的目标列表:
public ObservableCollection<ViewWrapper> GetViews() { // 提取所有视口对应的ViewId,存入HashSet以提升查找效率 var viewportViewIds = new FilteredElementCollector(Doc) .OfClass(typeof(Viewport)) .ToElements() .Select(x => new ViewportWrapper((Viewport)x)) .Select(vp => vp.ViewportViewId) .ToHashSet(); // 一次性获取所有非模板视图,避免重复添加 var allNonTemplateViews = new FilteredElementCollector(Doc) .OfCategory(BuiltInCategory.OST_Views) .WhereElementIsNotElementType() .ToElements() .Select(x => new ViewWrapper((View)x)) .Where(v => !v.ViewIsTemplate) .ToList(); // 筛选出未出现在视口列表中的非模板视图 var vNoSheet = allNonTemplateViews .Where(v => !viewportViewIds.Contains(v.ViewId)) .ToList(); return new ObservableCollection<ViewWrapper>(vNoSheet); }
关键改进点
- 用HashSet存储视口ViewId:HashSet的
Contains方法是O(1)时间复杂度,比List的O(n)查找效率高得多,数据量大时优势更明显。 - 一次性筛选非模板视图:直接在获取视图阶段就过滤掉模板视图,不用在循环里反复判断添加,避免重复元素。
- 单层筛选逻辑:直接从非模板视图中挑出ViewId不在视口集合里的元素,不会出现重复添加问题,自然得到唯一结果。
原代码问题复盘
- 嵌套循环冗余:外层每遍历一个视口,内层就重复添加符合条件的视图,导致元素重复累积。
vNoSheet初始化无效:初始时vList是空集合,vList.Distinct().ToList()得到的也是空列表,后续全靠循环添加重复元素。vList填充逻辑错误:每次循环都重复添加所有非模板视图,最终vList会有6×25=150个重复元素,完全不符合“列表2”的定位。
内容的提问来源于stack exchange,提问作者Gosmith
相关产品推荐
相关产品推荐

