VB.NET中如何用LINQ和Lambda检测重复及反向重复路线?
VB.NET检测反向重复路线的高效LINQ方案
要检测起点终点互换的反向重复路线,核心思路是让正向和反向路线生成相同的分组键,这样就能通过LINQ的GroupBy快速聚合重复项。以下是两种实用方案:
方案1:合并检测完全重复+反向重复
如果不需要区分完全重复和反向重复,直接用统一排序后的位置作为分组键,这样两种重复都会被归为同一组:
Dim duplicateAndReverseRoutes = Routes.Values.GroupBy(Function(route) ' 统一分组键:将两个位置按固定顺序排列,确保A→B和B→A生成相同键 If route.startLocation.CompareTo(route.destinationLocation) <= 0 Then New With {Key .FirstLoc = route.startLocation, Key .SecondLoc = route.destinationLocation} Else New With {Key .FirstLoc = route.destinationLocation, Key .SecondLoc = route.startLocation} End If ).Where(Function(group) group.Count() > 1).ToHashSet()
关键说明
- 这里依赖
startLocation和destinationLocation实现IComparable接口,如果是自定义类型,需要手动实现比较逻辑(比如比较坐标、ID等唯一标识)。 - 该方案会同时包含完全重复(起点终点完全相同)和反向重复的路线组。
方案2:仅检测纯反向重复(排除完全重复)
如果需要单独提取起点终点互换的反向重复(排除完全重复的路线),可以先按原始起点终点分组,再按反向键二次分组:
Dim pureReverseDuplicates = Routes.Values.GroupBy(Function(route) ' 第一步:按原始起点终点分组(区分完全重复的路线) New With {Key .Start = route.startLocation, Key .Dest = route.destinationLocation} ).GroupBy(Function(originalGroup) ' 第二步:对每个原始分组生成统一的反向键 If originalGroup.Key.Start.CompareTo(originalGroup.Key.Dest) <= 0 Then New With {Key .Loc1 = originalGroup.Key.Start, Key .Loc2 = originalGroup.Key.Dest} Else New With {Key .Loc1 = originalGroup.Key.Dest, Key .Loc2 = originalGroup.Key.Start} End If ).Where(Function(reverseGroup) reverseGroup.Count() > 1) ' 存在至少两个原始分组(正向+反向) .SelectMany(Function(reverseGroup) reverseGroup.SelectMany(Function(og) og)) ' 展开所有重复路线 .ToHashSet()
逻辑解释
- 第一次
GroupBy先把完全相同的路线归为一组; - 第二次
GroupBy用统一的反向键聚合这些组,若一个反向键对应多个组,说明存在正向和反向的路线; - 最后通过
SelectMany展开所有符合条件的重复路线。
内容的提问来源于stack exchange,提问作者Chiel
相关产品推荐
相关产品推荐

