Когда мы имеем дело с большим набором данных, бывает необходимым получать не сразу всю выборку элементов целиком, а получать их «постранично», например, последовательно по десять элементов. Для таких случаев в LINQ можно использовать такие методы расширения как Take и Skip.
Методы Take и Skip
Метод Take выбирает заданное количество элементов, начиная с первого, а метод Skip, напротив — пропускает заданное количество элементов, начиная с первого. Например:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var takeResult = numbers.Take(3);
foreach (int x in takeResult)
Console.Write($"{x} ");
Console.WriteLine();
var skipResult = numbers.Skip(3);
foreach (int x in skipResult)
Console.Write($"{x} ");
В результате получим следующий вывод в консоли:
1 2 3 4 5 6 7 8 9
Как и любые другие методы расширения LINQ методы Take и Skip можно комбинировать и выполнять последовательно. Например, мы можем выбрать три элемента, начиная с пятого:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var result = numbers.Skip(4).Take(3);
foreach (int x in result)
Console.Write($"{x} ");
Результат:
Методы TakeWhile и SkipWhile
Метод TakeWhile возвращает набор элементов последовательности, до тех пор, пока заданное условие истинно, а SkipWhile — пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы. Например, воспользуемся таким набором данных (рассматривали мы его здесь):
List<DataObject> objects = new List<DataObject>()
{
new DataObject {Name = "Измерение №1", Value = 12.5, Date = DateTime.Now },
new DataObject {Name = "Измерение №2", Value = 12.1, Date = DateTime.Now.AddDays(2) },
new DataObject {Name = "Измерение №3", Value = 80.5, Date = DateTime.Now.AddMonths(1) },
new DataObject {Name = "Измерение №4", Value = 11.3, Date = DateTime.Now.AddDays(7) },
new DataObject {Name = "Измерение №5", Value = 10.7, Date = DateTime.Now.AddHours(2.5) }
};
Выберем все элементы с начала, у которых значение Value меньше 50:
var result = objects.TakeWhile(x => x.Value < 50); foreach (DataObject data in result) Console.WriteLine(data.ToString());
Результат
Измерение №2 12,1 04.11.2021 14:33:38
Аналогичным образом, мы можем пропускать элементы и вернуть оставшуюся часть, используя метод SkipWhile:
var result = objects.SkipWhile(x => x.Value < 50); foreach (DataObject data in result) Console.WriteLine(data.ToString());
Результат:
Измерение №3 80,5 02.12.2021 14:35:57 Измерение №4 11,3 09.11.2021 14:35:57 Измерение №5 10,7 02.11.2021 17:05:57
Методы TakeLast и SkipLast
Методы TakeLast и SkipLast аналогичны методам Take и Last, но выбор элементов начинается не с начала, а с конца последовательности, при этом порядок элементов в исходной последовательности сохраняется. Например, выберем три последних элемента коллекции объектов:
var result = objects.TakeLast(3); foreach (DataObject data in result) Console.WriteLine(data.ToString());
Результат
Измерение №4 11,3 09.11.2021 14:40:23
Измерение №5 10,7 02.11.2021 17:10:23
Итого
Сегодня мы рассмотрели методы расширения LINQ, позволяющие проводить последовательный выбор элементов из коллекции с начала или с конца. Методы TakeXXX и SkipXXX удобно использовать для организации постраничного вывода результатов.