Вы можете создать метод расширения (я пропустил проверку источника здесь), который будет перебирать источник и создавать группы последовательные элементы. Если следующий элемент в источнике не подряд, то текущая группа дала:
public static IEnumerable<List<int>> ToConsecutiveGroups(
this IEnumerable<int> source)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
else
{
int current = iterator.Current;
List<int> group = new List<int> { current };
while (iterator.MoveNext())
{
int next = iterator.Current;
if (next < current || current + 1 < next)
{
yield return group;
group = new List<int>();
}
current = next;
group.Add(current);
}
if (group.Any())
yield return group;
}
}
}
Способ применения прост:
var listOfInt = new List<int> { 1, 2, 3, 4, 7, 8, 12, 13, 14 };
var groups = listOfInt.ToConsecutiveGroups();
Результат:
[
[ 1, 2, 3, 4 ],
[ 7, 8 ],
[ 12, 13, 14 ]
]
UPDATE: Вот общий версия этого метода расширения, который принимает предикат для проверки того, следует ли считать два значения последовательно:
public static IEnumerable<List<T>> ToConsecutiveGroups<T>(
this IEnumerable<T> source, Func<T,T, bool> isConsequtive)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
else
{
T current = iterator.Current;
List<T> group = new List<T> { current };
while (iterator.MoveNext())
{
T next = iterator.Current;
if (!isConsequtive(current, next))
{
yield return group;
group = new List<T>();
}
current = next;
group.Add(current);
}
if (group.Any())
yield return group;
}
}
}
Способ применения прост:
var result = listOfInt.ToConsecutiveGroups((x,y) => (x == y) || (x == y - 1));
, что является crieteria на основании которого вы split –
@ Co.Aden: Как они писали, им нужны смежные диапазоны чисел в отдельных подпоследовательностях. – Joey
@ Тогда это должно быть {1,2,3,4}, {7,8}, {12,13,14} –