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

如何筛选List<>中不在指定字符串内的元素?

问题分析

原代码存在两个核心问题:

  1. 遍历集合时直接删除元素导致索引异常:正向for循环中删除元素后,后续元素会自动前移,索引i递增会跳过下一个元素,出现漏判。
  2. 字符串包含判断逻辑错误:直接用FilterStr.Contains(属性值)会出现误匹配,比如属性值是"B"时,"NB|JA".Contains("B")会返回true,不符合精确匹配筛选值的需求。
解决方案

核心思路

先把|分隔的筛选字符串拆分为精确匹配的集合,再通过安全的方式筛选/删除元素,同时优化反射操作提升性能。


方案1:LINQ筛选(推荐,返回新集合)

这种方式不修改原集合,直接生成符合要求的新集合,逻辑清晰且避免索引问题:

// 拆分筛选字符串为HashSet,提升精确匹配的效率
var filterSet = new HashSet<string>(filterstr.Split('|', StringSplitOptions.RemoveEmptyEntries));

// 提前获取目标属性的反射信息,避免循环中重复反射
var targetProperty = typeof(DoorDetails).GetProperty(FilterOrder);
if (targetProperty == null)
{
    // 处理属性不存在的异常情况,比如返回空集合或抛出自定义异常
    return new List<DoorDetails>();
}

// 筛选属性值不在筛选集合中的元素
var filteredList = ListDoorData.Where(door => 
{
    var propertyValue = targetProperty.GetValue(door)?.ToString();
    return !filterSet.Contains(propertyValue);
}).ToList();

方案2:直接修改原集合(反向遍历删除)

如果需要直接修改原ListDoorData,采用反向遍历避免索引错乱:

var filterSet = new HashSet<string>(filterstr.Split('|', StringSplitOptions.RemoveEmptyEntries));
var targetProperty = typeof(DoorDetails).GetProperty(FilterOrder);
if (targetProperty == null)
    return;

// 反向遍历,删除元素不会影响未遍历的索引
for (int i = ListDoorData.Count - 1; i >= 0; i--)
{
    var propertyValue = targetProperty.GetValue(ListDoorData[i])?.ToString();
    if (filterSet.Contains(propertyValue))
    {
        ListDoorData.RemoveAt(i);
    }
}

方案3:批量删除(先收集待删元素)

另一种安全修改原集合的方式,先收集所有需要删除的元素,再批量移除:

var filterSet = new HashSet<string>(filterstr.Split('|', StringSplitOptions.RemoveEmptyEntries));
var targetProperty = typeof(DoorDetails).GetProperty(FilterOrder);
if (targetProperty == null)
    return;

// 收集所有需要删除的元素
var itemsToRemove = ListDoorData.Where(door => 
{
    var propertyValue = targetProperty.GetValue(door)?.ToString();
    return filterSet.Contains(propertyValue);
}).ToList();

// 批量移除
foreach (var item in itemsToRemove)
{
    ListDoorData.Remove(item);
}

关键优化点说明

  • HashSet的使用:相比List,HashSet的Contains方法时间复杂度为O(1),当筛选值较多时性能优势明显。
  • 反射优化:提前获取PropertyInfo,避免每次循环都重复调用GetType().GetProperty,减少性能损耗。
  • 空值处理:用?.ToString()处理属性值为null的情况,避免空引用异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:22:20