Содержание
Кроме фильтрации, выбора и группировки последовательностей в LINQ C# также предусмотрен ряд методов, позволяющих объединять как однородные, так и разнородные (содержащие элементы различных типов данных) коллекции.
Метод Concat
Метод Concat
объединяет две однородные коллекции. Например,
int[] integers = { 1, 2, 3, 4 }; int[] integers2 = { 5, 6, 7, 8 }; var result = integers.Concat(integers2); foreach (int i in result) Console.Write($"{i} ");
Вывод консоли
Метод Join
Позволяет объединить две разнородные коллекции по определенному признаку (ключу). Например, у нас уже есть класс, содержащий данные каких-то измерений:
public class DataObject { public string Name { get; set; } public double Value { get; set; } public DateTime Date { get; set; } public override string ToString() { return $"{Name} {Value} {Date}"; } }
Данные о том, кто именно проводил эти измерения содержатся в другом классе:
class Measurement { public string MeasurementName { get; set; } public string Person { get; set; } }
Коллекции будут выглядеть следующим образом:
List<DataObject> objects = new List<DataObject>() { new DataObject {Name = "Измерение №1", Value = 12.5, Date = DateTime.Now }, new DataObject {Name = "Измерение №2", Value = 12.5, Date = DateTime.Now }, 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) } }; List<Measurement> measurements = new List<Measurement>() { new Measurement {MeasurementName = "Измерение №1", Person = "Иван Иванов" }, new Measurement {MeasurementName = "Измерение №2", Person = "Петр Петров" }, new Measurement {MeasurementName = "Измерение №3", Person = "Семен Слепаков" }, new Measurement {MeasurementName = "Измерение №4", Person = "Вася Пупкин" }, new Measurement {MeasurementName = "Измерение №5", Person = "Николай Николаев" } };
Ключом, т.е. признаком по которому мы будем объединять две коллекции с помощью метода LINQ Join
может выступать название измерения, то есть — это поле Name
у класса DataObject
и поле MeasurementName
у класса Measurement
. Объединим две коллекции следующим образом:
var result = measurements.Join(objects, // <-- вторая коллекция p => p.MeasurementName, // свойство-ключ объекта из первой коллекции t => t.Name, // свойство-ключ объекта из второй коллекции (p, t) => new { Name = p.MeasurementName, Person = p.Person, Value = t.Value, Date = t.Date}); //что хотим видеть в результате
Результат:
Измерение №2 Петр Петров 12,5 06.11.2021 18:35:56
Измерение №3 Семен Слепаков 80,5 06.12.2021 18:35:56
Измерение №4 Вася Пупкин 11,3 13.11.2021 18:35:56
Измерение №5 Николай Николаев 10,7 06.11.2021 21:05:56
Метод Zip
Объединяет две коллекции последовательно в соответствии с их индексами, то есть первый элемент первой коллекции соединяется с первым элементов второй коллекции, второй элемент первой коллекции — со вторым элементов второй коллекции и так далее.
List<DataObject> objects = new List<DataObject>() { new DataObject {Name = "Измерение №1", Value = 12.5, Date = DateTime.Now }, new DataObject {Name = "Измерение №2", Value = 2.5, Date = DateTime.Now }, new DataObject {Name = "Измерение №3", Value = 12.5, Date = DateTime.Now }, new DataObject {Name = "Измерение №4", Value = 80.5, Date = DateTime.Now.AddMonths(1) }, new DataObject {Name = "Измерение №5", Value = 11.3, Date = DateTime.Now.AddDays(7) }, new DataObject {Name = "Измерение №6", Value = 10.7, Date = DateTime.Now.AddHours(2.5) }, new DataObject {Name = "Измерение №7", Value = 10.7, Date = DateTime.Now.AddHours(2.5) } }; List<Measurement> measurements = new List<Measurement>() { new Measurement {MeasurementName = "Измерение №3", Person = "Иван Иванов" }, new Measurement {MeasurementName = "Измерение №5", Person = "Петр Петров" }, new Measurement {MeasurementName = "Измерение №6", Person = "Семен Слепаков" }, new Measurement {MeasurementName = "Измерение №7", Person = "Вася Пупкин" }, new Measurement {MeasurementName = "Измерение №8", Person = "Николай Гиколаев" } }; var result = measurements.Zip(objects, // <-- вторая коллекция (p, t) => new { Name = p.MeasurementName, ObjectName = t.Name, Person = p.Person, Value = t.Value, Date = t.Date}); //что хотим ыидеть в результате foreach (var item in result) { Console.WriteLine($"{item.Name} - {item.ObjectName} {item.Person} {item.Value} {item.Date}"); }
Метод Zip
не проводит никаких проверок на равенство ключей, а просто «механически» соединяет две разнородные коллекции. Результат:
Измерение №5 — Измерение №2 Петр Петров 2,5 06.11.2021 18:48:54
Измерение №6 — Измерение №3 Семен Слепаков 12,5 06.11.2021 18:48:54
Измерение №7 — Измерение №4 Вася Пупкин 80,5 06.12.2021 18:48:54
Измерение №8 — Измерение №5 Николай Николаев 11,3 13.11.2021 18:48:54
Итого
Сегодня мы рассмотрели три метода объединения коллекций в LINQ C#: Concat
— объединяет две однородные коллекции, Zip
— объединяет две разнородные коллекции, Join
— объединяет две разнородные коллекции по ключу.