如何将遍历筛选水平近似对齐Rect的foreach循环转换为LINQ Lambda查询?
如何将遍历筛选水平近似对齐Rect的foreach循环转换为LINQ Lambda查询?
嘿,我来帮你把这段foreach循环转成更简洁的LINQ Lambda写法~ 先明确核心需求:你已经拿到了右侧列的Col集合,现在要找出allRects中每个Col项对应的水平近似对齐(Top值差小于2)的Rect,原来用foreach逐个查询,现在用LINQ来实现。
情况1:合并所有符合条件的Rect(去重)
如果你的目标是把所有和Col中任意项水平对齐的Rect合并成一个无重复的列表,可以用SelectMany来展开每个Col项对应的匹配集合:
// 把每个Col项对应的对齐Rect展开,再去重(避免同一个Rect被多次匹配) var allAlignedRects = Col .SelectMany(rt => allRects.Where(tb => Math.Abs(tb.BoundingBox.Top - rt.BoundingBox.Top) < 2)) .Distinct();
这个写法完全对应你原来的foreach逻辑:遍历每个rt,查询对应的rct,再把所有rct集合拼接成一个大列表,Distinct用来去除重复的Rect(如果同一个Rect和多个Col项的Top都接近的话)。
情况2:保留每个Col项对应的对齐集合
如果需要保留“参考Rect(Col中的项)+ 对应的对齐Rect列表”的关联关系,可以用Select映射成匿名对象:
// 为每个Col项生成包含自身和对应对齐Rect的集合 var alignedRectGroups = Col .Select(rt => new { ReferenceRect = rt, AlignedRects = allRects.Where(tb => Math.Abs(tb.BoundingBox.Top - rt.BoundingBox.Top) < 2).ToList() });
之后你可以遍历这个alignedRectGroups,像原来处理rct一样使用每个分组里的AlignedRects。
优化版:提前分组提升效率
如果allRects数据量比较大,上面的写法每次查询都要遍历整个allRects,效率会有点低。可以先把allRects按近似Top值分组,后续直接查分组就能得到结果:
// 先把allRects按近似Top分组(Top相差小于2的归为一组) var topAlignedGroups = allRects.GroupBy(tb => Math.Round(tb.BoundingBox.Top / 2) * 2); // 再为每个Col项找到对应的分组 var optimizedAlignedGroups = Col .Select(rt => { var targetTop = rt.BoundingBox.Top; // 找到和当前rt.Top相差小于2的分组 var matchedGroup = topAlignedGroups.FirstOrDefault(g => Math.Abs(g.Key - targetTop) < 2); return new { ReferenceRect = rt, AlignedRects = matchedGroup?.ToList() ?? new List<YourShapeType>() // 替换成你的实际类型 }; });
这种方式只需要对allRects遍历一次分组,后续查询都是直接找分组,性能会好很多~
内容来源于stack exchange
相关产品推荐
相关产品推荐

