这是我要分组的数据。
Start End
2 4
26 30
5 9
20 24
18 19
因为我有 18 - 19 和 20 - 24。我会将这两个加在一起作为 18 - 24。在这种情况下,规则是 (a, b) => b.start - a.end = 1 和结果会是
Start End
18 24
2 9
26 30
EDIT 根据下面的评论添加了最后的结果行。
最佳答案
因此,我们将从名为 GroupWhile
的辅助方法开始。它将提供一个谓词,该谓词接受序列中的两个项目,前一个和当前。如果该谓词返回 true,则当前项目与前一个项目进入同一组。如果没有,它会启动一个新组。
public static IEnumerable<IEnumerable<T>> GroupWhile<T>(
this IEnumerable<T> source, Func<T, T, bool> predicate)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
yield break;
List<T> list = new List<T>() { iterator.Current };
T previous = iterator.Current;
while (iterator.MoveNext())
{
if (!predicate(previous, iterator.Current))
{
yield return list;
list = new List<T>();
}
list.Add(iterator.Current);
previous = iterator.Current;
}
yield return list;
}
}
一旦我们有了这个,我们就可以按开始日期排序项目,然后按结束日期排序,在前一个范围的结束与下一个范围的开始重叠时对它们进行分组,然后根据组开始将每个组折叠到一个新范围中和最终值(value)。
var collapsedRanges = ranges.OrderBy(range => range.Start)
.ThenBy(range => range.End)
.GroupWhile((prev, cur) => prev.End + 1 >= cur.Start)
.Select(group => new Range()
{
Start = group.First().Start,
End = group.Select(range => range.End).Max(),
});
关于c# - 如何在 LINQ 中对范围进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22255438/