如何将“相邻”网站分组:
给定数据:
List<Site> sites = new List<Site> {
new Site { RouteId="A", StartMilepost=0.00m, EndMilepost=1.00m },
new Site { RouteId="A", StartMilepost=1.00m, EndMilepost=2.00m },
new Site { RouteId="A", StartMilepost=5.00m, EndMilepost=7.00m },
new Site { RouteId="B", StartMilepost=3.00m, EndMilepost=5.00m },
new Site { RouteId="B", StartMilepost=11.00m, EndMilepost=13.00m },
new Site { RouteId="B", StartMilepost=13.00m, EndMilepost=14.00m },
};
Run Code Online (Sandbox Code Playgroud)
我想要结果:
[
[
Site { RouteId="A", StartMilepost=0.00m, EndMilepost=1.00m },
Site { RouteId="A", StartMilepost=1.00m, EndMilepost=2.00m }
],
[
Site { RouteId="A", StartMilepost=5.00m, EndMilepost=7.00m }
],
[
Site { RouteId="B", StartMilepost=3.00m, EndMilepost=5.00m }
],
[
Site { RouteId="B", StartMilepost=11.00m, EndMilepost=13.00m },
Site { RouteId="B", StartMilepost=13.00m, EndMilepost=14.00m }
]
]
Run Code Online (Sandbox Code Playgroud)
我尝试使用具有自定义比较器功能的GroupBy来检查routeIds匹配,并且第一个站点的终点里程等于下一个站点的起点里程。我的HashKey函数只是签出routeId,因此路由中的所有站点都将被合并在一起,但我认为比较器会做出一个假设,例如,如果A = B,并且B = C,那么A = C,因此C不会与A分组,B,C,因为在我的邻接案例中,A将不等于C。
我很惊讶它GroupBy没有超载Func<..., bool>就地分组而无需实现自定义类的麻烦。
所以我创建了一个:
public static IEnumerable<IEnumerable<T>> GroupBy<T>(this IEnumerable<T> source, Func<T, T, bool> func)
{
var items = new List<T>();
foreach (var item in source)
{
if (items.Count != 0)
if (!func(items[0], item))
{
yield return items;
items = new List<T>();
}
items.Add(item);
}
if (items.Count != 0)
yield return items;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var result = sites.GroupBy((x, y) => x.RouteId == y.RouteId &&
x.StartMilepost <= y.EndMilepost && x.EndMilepost >= y.StartMilepost).ToList();
Run Code Online (Sandbox Code Playgroud)
这应该会产生想要的结果。
关于实施的几句话。在上面的扩展方法中,您必须提供委托,如果x和y应该分组,该委托应该返回 true。该方法很愚蠢,只会按照相邻项目出现的顺序进行比较。您的输入是有序的,但您可能必须在将其与其他内容一起使用之前使用OrderBy/ 。ThenBy
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |