如何使用LINQ在双条件下从另一个List<>更新目标List<>?
用LINQ实现双条件嵌套循环的更新逻辑
先明确你的原有代码逻辑:遍历curPrefCalc集合中的每个pCalc,当pCalc.IsVariable为true时,再遍历primeRt集合,只要满足以下任一条件,就将pCalc.VariableRate设置为当前pr.Rate:
pCalc.prefbeg >= pr.BegDate且pCalc.prefend <= pr.EndDatepCalc.prefbeg >= pr.BegDate(且不满足第一个条件)
注意:原有代码中如果多个pr符合条件,最后一个符合条件的pr.Rate会覆盖之前的赋值,以下LINQ实现会匹配这个行为。
实现代码
方式1:与原逻辑完全对齐的LINQ写法
用LINQ筛选出需要处理的对象,再按原逻辑遍历赋值:
foreach (var pCalc in curPrefCalc.Where(p => p.IsVariable)) { var matchingRates = primeRt.Where(pr => (pCalc.prefbeg >= pr.BegDate && pCalc.prefend <= pr.EndDate) || pCalc.prefbeg >= pr.BegDate); foreach (var pr in matchingRates) { pCalc.VariableRate = pr.Rate; } }
方式2:优化效率(直接取最后一个符合条件的Rate)
原代码本质是用最后一个符合条件的pr.Rate覆盖结果,因此可以直接定位到该记录,减少不必要的赋值操作:
foreach (var pCalc in curPrefCalc.Where(p => p.IsVariable)) { var lastMatchingPr = primeRt.LastOrDefault(pr => (pCalc.prefbeg >= pr.BegDate && pCalc.prefend <= pr.EndDate) || pCalc.prefbeg >= pr.BegDate); if (lastMatchingPr != null) { pCalc.VariableRate = lastMatchingPr.Rate; } }
方式3:简化条件(合并冗余判断)
仔细看两个条件,第一个条件是第二个条件的子集(已经包含pCalc.prefbeg >= pr.BegDate),因此可以直接合并为单一条件,逻辑完全等价:
foreach (var pCalc in curPrefCalc.Where(p => p.IsVariable)) { var lastMatchingPr = primeRt.LastOrDefault(pr => pCalc.prefbeg >= pr.BegDate); if (lastMatchingPr != null) { pCalc.VariableRate = lastMatchingPr.Rate; } }
补充说明
LINQ更擅长数据查询而非直接修改对象属性,因此最终仍需要通过foreach完成属性更新(若用Select会创建新对象,无法修改原集合中的元素)。如果primeRt是按BegDate倒序排列的,LastOrDefault会自动取到最新的符合条件的记录,和原代码遍历后的结果一致。
内容的提问来源于stack exchange,提问作者MarioSalento
相关产品推荐
相关产品推荐

