Давайте создадим общий ответ.Тот, который работает для любой последовательности любой длины, где вы хотите разбить последовательность на последовательность подпоследовательностей, где каждая подпоследовательность имеет указанную длину, за исключением, может быть, последней:
Например:
IEnumerable<int> items = {10, 11, 12, 13, 14, 15, 16, 17};
// split into subsequences of length 3:
IEnumerable<IEnumerable> splitSequence = items.Split(3);
// splitSequence is a sequence of 3 subsequences:
// {10, 11, 12},
// {13, 14, 15},
// {16, 17}
Мы сделаем это, создав метод расширения.Таким образом, метод Split может использоваться как любая функция LINQ.См. Расширение методов демистификации .Чтобы сделать это эффективным, я буду перечислять только один раз, и я не буду перечислять больше элементов, чем запрашивается.
IEnumerable<TSource> Split(this IEnumerable<TSource> source, int splitSize)
{
// TODO: exception if null source, or non-positive splitSize
// Get the enumerator and enumerate enough elements to return
IEnumerator<TSource> enumerator = source.GetEnumerator();
while (enumerator.MoveNext())
{
// there are still items in the source; fill a new sub-sequence
var subSequence = new Tsource[SplitSize];
int index = 0;
do
{
subSequence[index] = enumerator.Current;
++index;
}
// repeat this until the subSequence is full or until source has no more elements
while (index < splitSize && enumerator.MoveNext());
// return the subSequence
yield return subSequence;
}
}
Использование:
// Get all Students that live in New York, split them into groups of 10 Students
// and return groups that have at least one Law Student
var newYorkLasStudentGroups = GetStudents();
.OrderBy(student => student.UniversityLocation == "New York")
.Split(10)
.Where(studentGroup => studentGroup.Any(student => student.Study == "Law"));