Метод SelectMany позволяет свести набор коллекций в одну коллекцию. Он имеет ряд перегруженных версий. Возьмем одну из них:
SelectMany(Func> selector);
SelectMany(Func> collectionSelector, Func resultSelector);
|
Первая версия метода принимает функцию преобразования в виде делегата Func>. Функция преобразования получает каждый объект выборки типа TSource и с его помощью создает набор объектов TResult. Метод SelectMany возвращает коллекцию преобразованных объектов.
Вторая версия принимает функцию преобразования в виде делегата Func>. Функция преобразования получает каждый объект выборки типа TSource и возвращает некоторую промежуточную коллекцию типа TCollection. Второй параметр - то же функция функция преобразования в виде делегата Func, которая получает два параметра - каждый элемент текущей выборки и каждый элемент промежуточной коллекции и на их основе создает некоторый объект типа TResult.
Рассмотрим следующий пример:
var companies = new List
{
new Company("Microsoft", new List
{new Person("Tom"), new Person("Bob")}),
new Company("Google", new List
{new Person("Sam"), new Person("Mike")}),
};
var employees = companies.SelectMany(c => c.Staff);
foreach (var emp in employees)
Console.WriteLine($"{emp.Name}");
record class Company(string Name, List
Staff);
record class Person(string Name);
|
Здесь нам дан список компаний, в каждой компании имеет набор сотрудников в виде списка объектов Person. И на выходе мы получаем список сотрудников всех компаний, то есть по сути коллекцию объектов Person. Консольный вывод:
Tom
Bob
Sam
Mike
Аналогичный пример с помощью операторов LINQ:
var companies = new List
{
new Company("Microsoft", new List
{new Person("Tom"), new Person("Bob")}),
new Company("Google", new List
{new Person("Sam"), new Person("Mike")}),
};
var employees = from c in companies
from emp in c.Staff
select emp;
foreach (var emp in employees)
Console.WriteLine($"{emp.Name}");
record class Company(string Name, List
Staff);
record class Person(string Name);
|
Теперь добавим к сотрудникам их компанию:
var companies = new List
{
new Company("Microsoft", new List
{new Person("Tom"), new Person("Bob")}),
new Company("Google", new List
{new Person("Sam"), new Person("Mike")}),
};
var employees = companies.SelectMany(c => c.Staff,
(c, emp)=> new { Name = emp.Name, Company = c.Name});
foreach (var emp in employees)
Console.WriteLine($"{emp.Name} - {emp.Company}");
record class Company(string Name, List
Staff);
record class Person(string Name);
|
Здесь применяется другая версия метода SelectMany. Первый делегат в виде c => c.Staff создает промежуточную коллекцию - фактически просто возвращаем набор сотрудников каждой компании. Второй делегат - (c, emp)=> new { Name = emp.Name, Company = c.Name } получает каждую компанию и каждый элемент промежуточной коллекции - объект Person и на их основе создает анонимный объект с двумя свойствами Name и Company. Консольный вывод программы:
Tom - Microsoft
Bob - Microsoft
Sam - Google
Mike - Google
Аналогичный пример с помощью операторов запросов:
var companies = new List
{
new Company("Microsoft", new List
{new Person("Tom"), new Person("Bob")}),
new Company("Google", new List
{new Person("Sam"), new Person("Mike")}),
};
var employees = from c in companies
from emp in c.Staff
select new { Name = emp.Name, Company = c.Name };
foreach (var emp in employees)
Console.WriteLine($"{emp.Name} - {emp.Company}");
record class Company(string Name, List
Staff);
record class Person(string Name);
|
Do'stlaringiz bilan baham: |