Here is an extension method taken from http://bugsquash.blogspot.com/2010/01/grouping-consecutive-integers-in-c.html
public static IEnumerable> GroupConsecutive(this IEnumerable list) {
var group = new List();
foreach (var i in list) {
if (group.Count == 0 || i - group[group.Count - 1] <= 1)
group.Add(i);
else {
yield return group;
group = new List {i};
}
}
yield return group;
}
You can use it like this:
var numbers = new[] { 1, 2, 3, 4, 6, 7, 9 };
var groups = numbers.GroupConsecutive();
Once C# 7 is released, this can made even more efficient with the use of Span to avoid creating new lists.
This updated version does it without allocating any lists.
public static class EnumerableExtensions
{
public static IEnumerable> GroupConsecutive(this IEnumerable list)
{
if (list.Any())
{
var count = 1;
var startNumber = list.First();
int last = startNumber;
foreach (var i in list.Skip(1))
{
if (i < last)
{
throw new ArgumentException($"List is not sorted.", nameof(list));
}
if (i - last == 1)
count += 1;
else
{
yield return Enumerable.Range(startNumber, count);
startNumber = i;
count = 1;
}
last = i;
}
yield return Enumerable.Range(startNumber, count);
}
}
}