Объединить коллекции
что именно вы хотите получить? Также что из себя представляют ‘bnb три коллекции?
14 июл 2015 в 14:44
Хочу Foreach вывести все в Gridview. Коллекции это выборка по JSON файлу
14 июл 2015 в 14:47
Gridview и foreach отношения к вопросу не имеют. Каким должен быть результат? И что это за выборки? У вас слишком расплывчатый вопрос
14 июл 2015 в 14:48
Как мне соединить все три коллекции как в случаи с Linq. Хочу обращаться к полям по именам.
Заполнение коллекций объектов из нескольких источников (LINQ) (C#)
В этом примере показано, как объединить данные из разных источников в последовательность новых типов.
Не пытайтесь объединить данные в памяти или данные в файловой системе с данными, которые остаются в базе данных. Такие междоменные соединения могут повлечь за собой непредвиденные результаты из-за разных способов, с помощью которых операции соединения могут определяться для запросов к базам данных и другим типам источников. Кроме того, существует риск, что такая операция может вызвать исключение нехватки памяти, если объем данных в базе данных достаточно большой. Чтобы объединить данные из базы данных с данными в памяти, сначала вызовите ToList или ToArray для запроса к базе данных, а затем выполните присоединение для возвращенной коллекции.
Создание файла данных
Скопируйте файлы names.csv и scores.csv в папку проекта, как описано в руководстве по объединению содержимого из файлов разных форматов (LINQ) (C#).
Пример
Следующий пример демонстрирует использование именованного типа Student для хранения объединенных данных из двух коллекций строк в памяти, которые имитируют данные электронной таблицы в формате CSV. Первая коллекция строк представляет имена и идентификаторы учащихся, а вторая коллекция — идентификатор учащегося (в первом столбце) и результаты четырех экзаменов. Идентификатор используется в качестве внешнего ключа.
using System; using System.Collections.Generic; using System.Linq; class Student < public string FirstName < get; set; >public string LastName < get; set; >public int ID < get; set; >public List ExamScores < get; set; >> class PopulateCollection < static void Main() < // These data files are defined in How to join content from // dissimilar files (LINQ). // Each line of names.csv consists of a last name, a first name, and an // ID number, separated by commas. For example, Omelchenko,Svetlana,111 string[] names = System.IO.File.ReadAllLines(@"../../../names.csv"); // Each line of scores.csv consists of an ID number and four test // scores, separated by commas. For example, 111, 97, 92, 81, 60 string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv"); // Merge the data sources using a named type. // var could be used instead of an explicit type. Note the dynamic // creation of a list of ints for the ExamScores member. The first item // is skipped in the split string because it is the student ID, // not an exam score. IEnumerablequeryNamesScores = from nameLine in names let splitName = nameLine.Split(',') from scoreLine in scores let splitScoreLine = scoreLine.Split(',') where Convert.ToInt32(splitName[2]) == Convert.ToInt32(splitScoreLine[0]) select new Student() < FirstName = splitName[0], LastName = splitName[1], ExamScores = (from scoreAsText in splitScoreLine.Skip(1) select Convert.ToInt32(scoreAsText)). ToList() >; // Optional. Store the newly created student objects in memory // for faster access in future queries. This could be useful with // very large data files. List students = queryNamesScores.ToList(); // Display each student's name and exam score average. foreach (var student in students) < Console.WriteLine("The average score of is .", student.FirstName, student.LastName, student.ExamScores.Average()); > //Keep console window open in debug mode Console.WriteLine("Press any key to exit."); Console.ReadKey(); > > /* Output: The average score of Omelchenko Svetlana is 82.5. The average score of O'Donnell Claire is 72.25. The average score of Mortensen Sven is 84.5. The average score of Garcia Cesar is 88.25. The average score of Garcia Debra is 67. The average score of Fakhouri Fadi is 92.25. The average score of Feng Hanying is 88. The average score of Garcia Hugo is 85.75. The average score of Tucker Lance is 81.75. The average score of Adams Terry is 85.25. The average score of Zabokritski Eugene is 83. The average score of Tucker Michael is 92. */
В предложении select инициализатор объектов используется для создания каждого нового объекта Student на основе данных из двух источников.
Если не требуется хранить результаты запроса, анонимные типы могут быть более удобными, чем именованные типы. Именованные типы необходимы, если результаты запроса передаются за пределы метода, в котором выполняется запрос. Следующий пример кода выполняет ту же задачу, что и в предыдущем примере, но использует анонимные типы вместо именованных типов:
// Merge the data sources by using an anonymous type. // Note the dynamic creation of a list of ints for the // ExamScores member. We skip 1 because the first string // in the array is the student ID, not an exam score. var queryNamesScores2 = from nameLine in names let splitName = nameLine.Split(',') from scoreLine in scores let splitScoreLine = scoreLine.Split(',') where Convert.ToInt32(splitName[2]) == Convert.ToInt32(splitScoreLine[0]) select new < First = splitName[0], Last = splitName[1], ExamScores = (from scoreAsText in splitScoreLine.Skip(1) select Convert.ToInt32(scoreAsText)) .ToList() >; // Display each student's name and exam score average. foreach (var student in queryNamesScores2) < Console.WriteLine("The average score of is .", student.First, student.Last, student.ExamScores.Average()); >
См. также
- Инициализаторы объектов и коллекций
- Анонимные типы
Как объединить две коллекции c
Соединение в LINQ используется для объединения двух разнотипных наборов в один. Для соединения используется оператор join или метод Join() . Как правило, данная операция применяется к двум наборам, которые имеют один общий критерий.
Оператор join
Оператор join имеет следующий формальный синтаксис:
from объект1 in набор1 join объект2 in набор2 on объект2.свойство2 equals объект1.свойство1
После оператора join идет выборка объектов из второй коллекции. После оператора on указывается критерий соединения — свойство объекта из второй выборки, а после оператора equals — свойство объекта из первой выборки, которому должно быть равно свойство объекта из второй выборки. Если эти свойства равны, то оба объекта попадают в финальный результат.
Например, у нас есть два класса:
record class Person(string Name, string Company); record class Company(string Title, string Language);
Класс Person представляет пользователя и хранит два свойства: Name (имя) и Company (компания пользователя). Класс Company представляет компанию и хранит два свойства: Title (название компании) и Language (основной язык программирования в компании)
Объекты обоих классов будет иметь один общий критерий — название компании. Соединим по этому критерию два набора этих классов:
Person[] people = < new Person("Tom", "Microsoft"), new Person("Sam", "Google"), new Person("Bob", "JetBrains"), new Person("Mike", "Microsoft"), >; Company[] companies = < new Company("Microsoft", "C#"), new Company("Google", "Go"), new Company("Oracle", "Java") >; var employees = from p in people join c in companies on p.Company equals c.Title select new < Name = p.Name, Company = c.Title, Language = c.Language >; foreach (var emp in employees) Console.WriteLine($" - ()"); record class Person(string Name, string Company); record class Company(string Title, string Language);
С помощью выражения
join c in companies on p.Company equals c.Title
объект p из списка people (то есть объект Person) соединяется с объектом c из списка companies (то есть с объектом Company), если значение свойства p.Company совпадает со значением свойства c.Title . Результатом соединения будет объект анонимного типа, который будет содержать три свойства. В итоге мы получим следующий вывод:
Tom - Microsoft (C#) Sam - Google (Go) Mike - Microsoft (C#)
Обратите внимание, что в массиве people есть объект new Person(«Bob», «JetBrains») , но в массиве компаний компании с именем «JetBrains» нет, соответственно он не попал с результат. Аналогично в списке people нет объектов Person, которые бы соотствовали компании new Company(«Oracle», «Java») .
Метод Join
В качестве альтернативы можно было бы использовать метод Join() :
Join(IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector);
Метод Join() принимает четыре параметра:
- второй список, который соединяем с текущим
- делегат, который определяет свойство объекта из текущего списка, по которому идет соединение
- делегат, который определяет свойство объекта из второго списка, по которому идет соединение
- делегат, который определяет новый объект в результате соединения
Перепишим предыдущий пример с использованием метода Join:
Person[] people = < new Person("Tom", "Microsoft"), new Person("Sam", "Google"), new Person("Bob", "JetBrains"), new Person("Mike", "Microsoft"), >; Company[] companies = < new Company("Microsoft", "C#"), new Company("Google", "Go"), new Company("Oracle", "Java") >; var employees = people.Join(companies, // второй набор p => p.Company, // свойство-селектор объекта из первого набора c => c.Title, // свойство-селектор объекта из второго набора (p, c) => new < Name = p.Name, Company = c.Title, Language = c.Language >); // результат foreach (var emp in employees) Console.WriteLine($" - ()"); record class Person(string Name, string Company); record class Company(string Title, string Language);
GroupJoin
Метод GroupJoin() кроме соединения последовательностей также выполняет и группировку.
GroupJoin(IEnumerable inner, Func outerKeySelector, Func innerKeySelector, FuncresultSelector);
Метод GroupJoin() принимает четыре параметра:
- второй список, который соединяем с текущим
- делегат, который определяет свойство объекта из текущей коллекции, по которому идет соединение и по которому будет идти группировка
- делегат, который определяет свойство объекта из второй коллекции, по которому идет соединение
- делегат, который определяет новый объект в результате соединения. Этот делегат получает группу — объект текущей коллекции, по которому шла группировка, и набор объектов из второй коллекции, которые сооставляют группу
Например, возьмем выше определенные массивы people и companies и сгуппируем всех пользователей по компаниям:
Person[] people = < new Person("Tom", "Microsoft"), new Person("Sam", "Google"), new Person("Bob", "JetBrains"), new Person("Mike", "Microsoft"), >; Company[] companies = < new Company("Microsoft", "C#"), new Company("Google", "Go"), new Company("Oracle", "Java") >; var personnel = companies.GroupJoin(people, // второй набор c => c.Title, // свойство-селектор объекта из первого набора p => p.Company, // свойство-селектор объекта из второго набора (c, employees) => new // результат < Title = c.Title, Employees = employees >); foreach (var company in personnel) < Console.WriteLine(company.Title); foreach(var emp in company.Employees) < Console.WriteLine(emp.Name); >Console.WriteLine(); > record class Person(string Name, string Company); record class Company(string Title, string Language);
Результатом выполнения программы будет следующий вывод:
Microsoft Tom Mike Google Sam Oracle
Метод GroupJoin, также как и метод Join, принимает все те же параметры. Только теперь в последний параметр — делегат передаются объект компании и набор пользователей этой компании.
Обратите внимание, что для компании «Oracle» в массиве people нет пользователей, хотя для нее также создается группа.
Аналогичного результата можно добитьс и с помощью оператора join:
var personnel = from c in companies join p in people on c.Title equals p.Company into g select new // результат < Title = c.Title, Employees = g >;
Метод Zip
Метод Zip() последовательно объединяет соответствующие элементы текущей последовательности со второй последовательностью, которая передается в метод в качестве параметра. То есть первый элемент из первой последовательности объединяется с первым элементом из второй последовательности, второй элемент из первой последовательности соединяется со вторым элементом из второй последовательности и так далее. Результатом метода является коллекция кортежей, где каждый кортеж хранит пару соответствующих элементов из обоих последовательностей:
var courses = new List < new Course("C#"), new Course("Java") >; var students = new List < new Student("Tom"), new Student("Bob") >; var enrollments = courses.Zip(students); foreach (var enrollment in enrollments) Console.WriteLine($" - "); record class Course(string Title); // учебный курс record class Student(string Name); // студент
Здесь метод Zip объединяет соответствующие элементы из списков courses и students. В результате создается новая коллекция, которая хранит набор кортежей. Каждый кортеж в ней имеет два элемента. Первый элемент из свойства First представляет объект текущей коллекции (в данном случае объект Course), а второй элемент (в свойстве Second) хранит объект второй последовательности (в данном случае объект Student). Консольный вывод:
Course < Title = C# >— Student < Name = Tom >Course < Title = Java >— Student
Как объединить не сколько коллекций в одну?
Приветствую всех! Сегодня хочу показать пример как с помощь LINQ, объединить коллекцию в одну. По условию задания у нас дана коллекция, главный метод и метод который мы должны дописать:
public class Classroom
public List < string >Students = new List < string >( ) ;
public static void Main ( )
Classroom [ ] classes =
new Classroom < Students = < "Pavel" , "Ivan" , "Petr" >, > ,
new Classroom < Students = < "Anna" , "Ilya" , "Vladimir" >, > ,
new Classroom < Students = < "Bulat" , "Alex" , "Galina" >, >
var allStudents = GetAllStudents ( classes ) ;
Array . Sort ( allStudents ) ;
Console . WriteLine ( string . Join ( » » , allStudents ) ) ;
public static string [ ] GetAllStudents ( Classroom [ ] classes )
Как видно в метод GetAllStudents принимает коллекцию коллекций. А вернуть нам нужно массив string[] Который содержит имена всех студентов.
Решение этой тривиальной задачи будет в одну строчку кода, которую мы решим с помощью Linq:
public static string [ ] GetAllStudents ( Classroom [ ] classes )
return classes . SelectMany ( s = > s . Students ) . ToArray ( ) ;
Для решения этой задачи воспользуемся методом SelectMany, почитать можете в чем разница между Select и SelectMany тут всю коллекцию преобразуем в массив string() с помощью метода ToArray();