使用C# LINQ在嵌套列表中查找并更新值(无foreach)
实现方案
前置性能优化
先把CorrectValues处理成可快速查找的字典索引,毕竟同name的correctValue完全一致,完全没必要每次匹配都全表扫:
// 按name分组去重,构建O(1)查找的映射 var correctValueMap = correctValues .GroupBy(cv => cv.name) .ToDictionary(g => g.Key, g => g.First().correctValue);
之前写法的问题
你尝试的LINQ写法有个硬伤:outerObjects.Select(q => q.InnerObjects) 这一步直接把外层OuterObjects的name信息丢了,后续根本没法匹配对应name的CorrectValues,相当于筛出来的内部对象完全不知道自己属于哪个外层、该对应哪个正确值,逻辑上是走不通的。
无嵌套foreach的实现逻辑
所有关联、筛选、条件判断全部用LINQ完成,不需要手写两层嵌套的循环判断:
// 全LINQ完成关联、筛选,无嵌套逻辑 var updateTargets = theList // 给每个外层对象绑定自己对应的correct值 .Select(outer => new { OuterInstance = outer, MatchedValue = correctValueMap.TryGetValue(outer.name, out var val) ? val : (float?)null }) // 直接跳过没有匹配到正确值的外层对象 .Where(x => x.MatchedValue.HasValue) // 展开内部对象列表,筛选满足 small > big 的待更新条目 .SelectMany(x => x.OuterInstance.myList .Where(inner => inner.small > inner.big) .Select(inner => new { InnerReference = inner, NewBigValue = x.MatchedValue.Value }) );
完成最终赋值
说明:对象字段修改是可变状态操作,本身必须依托遍历完成,但这里已经把所有复杂的匹配、判断逻辑全部拆解为LINQ的纯查询步骤,最后一步只需要对筛选好的目标做极简赋值,完全不需要在嵌套循环里写多分支判断。
因为InnerObjects是引用类型,上面筛选出来的InnerReference直接指向内存里的原对象,赋值会直接生效在原始数据上:
foreach (var target in updateTargets) { target.InnerReference.big = target.NewBigValue; }
如果连这层单循环都不想写,也可以借助LINQ的Aggregate方法完成赋值,本质逻辑和单循环一致,只是语法形式不同。
关键注意点
- 同name的correctValue完全一致,所以分组后取第一条的操作没有数据偏差
- 提前建字典索引的方式,能把整体匹配的时间复杂度从O(数据量*CorrectValues长度)降到线性的O(数据量),哪怕数据量达到十万级也不会有性能卡顿
内容的提问来源于stack exchange,提问作者cdub
相关产品推荐
相关产品推荐

