You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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不在视口集合里的元素,不会出现重复添加问题,自然得到唯一结果。
原代码问题复盘
  1. 嵌套循环冗余:外层每遍历一个视口,内层就重复添加符合条件的视图,导致元素重复累积。
  2. vNoSheet初始化无效:初始时vList是空集合,vList.Distinct().ToList()得到的也是空列表,后续全靠循环添加重复元素。
  3. vList填充逻辑错误:每次循环都重复添加所有非模板视图,最终vList会有6×25=150个重复元素,完全不符合“列表2”的定位。

内容的提问来源于stack exchange,提问作者Gosmith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:35:16