Секреты LINQ. Автогенерируемые свойства. Инициализаторы объектов и коллекций, страница 16

N

Группа операций

Операции

1

Фильтрация (Filtering)

Where, OfType

2

Проецирование (Projection)

Select, SelectMany

3

Разбиение (Partitioning)

Take, TakeWhile, Skip, SkipWhile

4

Объединение (Join)

Join, GroupJoin

5

Слияние (Concatenation)

Concat

6

Сортировка (Ordering)

OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse

7

Группировка (Grouping)

GroupBy, ToLookup

8

Операции с множествами (Set)

Distinct, Union, Intersect, Except

9

Преобразование (Conversion)

AsEnumerable, AsQueryable, ToArray, ToList, ToDictionary, Cast, OfType, ToLookup

10

Проверка равенства (Equality)

SequenceEqual

11

Операции с элементами

ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault,

12

Генерирование (Generation)

DefaultIfEmpty, Empty, Range, Repeat

13

Кванторы (Quantifiers)

Any, All, Contains

14

Агрегирование (Aggregate)

Count, LongCount, Sum, Min, Max, Average, Aggregate

Фильтрация данных

Рассмотрим пример использования extension-метода Where, используемого для фильтрации элементов произвольной последовательности. Этот метод расширяет все последовательности IEnumerable<T> и имеет две совмещенные версии. Первая версия имеет прототип:

public static IEnumerable<T> Where<T>(this IEnumerable<T> src, Func<T,bool> pred);

Переменная pred является generic-делегатом типа Func <T, bool> и задает функцию-предикат. Напомним, что предикатом называется любая функция, которая возвращает значение типа bool.

Метод Where пробегает по входной последовательности src и для каждого ее элемента вызывает функцию-предикат. Если результатом вызова предиката будет true, то элемент помещается в выходную последовательность, если — false, то нет. Можно сказать, что предикат является подобием пропуска (фильтра) для элемента входной последовательности. Он решает, можно ли пропустить элемент в выходную последовательность. Приведем пример фильтрации последовательности текстовых строк.

string line = new string('\u2500', 22);

Console.WriteLine(line + "Test Where");

string[] words = { "cool", "google", "bool", "true", "soon", "do", "bootable", "zoom", "bottom" };

var q = words.Where(c => c.Contains("oo"));

Console.WriteLine("Words containing 'oo':\n" + line);

foreach (var s in q)

Console.WriteLine(s + "\t" + s.Length);

Результат вызова метода Where — это объект, реализующий интерфейс IEnumerable<string>. Этот объект способен выполнить проход по последовательности и отфильтровать данные. Ссылка на него попадает в переменную q (с семантикой query). Лямбда-выражение c=>c.Contains("oo") задает и параметр и тело функции-предиката. Переменная с — это параметр, а выражение c.Contains("oo") — тело предиката. Тело функции должно соответствовать делегату с сигнатурой Func<T,bool>. Так как метод Contains возвращает bool, то это условие в нашем случае выполнено. Строки массива фильтруются с помощью λ-выражения и на выходе остаются только слова, содержащие подстроку "oo".

Вторая версия extension-метода Where имеет более сложную сигнатуру:

public static IEnumerable<T> Where<T>(this IEnumerable<T> src, Func<T,int,bool> pred);