Разбираемся с Linq

Приветствую всех, сегодня начнем разбираться с Linq, урок будет длинным но надеюсь продуктивным и позволит вам разобраться с ними, надеюсь хотя бы вопросов станет при использовании у вас меньше. А так же поймете всю мощь и скорость проектирования с помощью Linq.

Когда не было линков, разработчики использовали в своих приложениях в основном колекци, и это превращало большие проекты в  сущий кошмар, для тех кто его поддерживал. При появлении linq сократилось время разработки и код программ мог уменьшиться аж в 10 раз, а понимание и читаемость кода увеличиться, потому сейчас 2018 год и использование linq повсеместно в разработке.

Давайте рассмотрим как создавали код до линков:

public class Student
	{
		public string LastName { get; set; }
		public string Group { get; set; }
	}

	public class Program
	{
		public static void Main()
		{
			var students = new List<Student>
		{
			new Student { LastName="Andrey", Group="ПМТ-1" },
			new Student { LastName="Sergey", Group="ПМТ-1" },
			new Student { LastName="Alexandr", Group="ПК-1"},
			new Student { LastName="Vladimir", Group="ПК-1"}
		};

			var result = new List<string>();
			foreach (var s in students)
				if (s.Group == "ПК-1")
					result.Add(s.LastName);

			foreach (var name in result)
					Console.WriteLine(name);

					Console.ReadKey();
			
		}
	}

//Alexandr
//Vladimir

В коде ничего сложного, просто мы создали класс студентов и поместили в коллекции самих студентов по группам. И осуществили поиск в коллекции в посоответствию если есть студенты в группе ПК-1, то поместить их в другу коллекцию и вывести их имена.

А теперь давайте рассмотрим тот же код но используем Linq:

public class Student
	{
		public string LastName { get; set; }
		public string Group { get; set; }
	}

	public class Program
	{
		public static void Main()
		{
			var students = new List<Student>
		{
			new Student { LastName="Andrey", Group="ПМТ-1" },
			new Student { LastName="Sergey", Group="ПМТ-1" },
			new Student { LastName="Alexandr", Group="ПК-1"},
			new Student { LastName="Vladimir", Group="ПК-1"}
		};
			
			var result = students.Where(z => z.Group == "ПК-1").Select(z => z.LastName).ToList();
				foreach (var name in result)
				Console.WriteLine(name);

			Console.ReadKey();
		}
	}

//Alexandr
//Vladimir

Метод ToList  будет выполняться первым, вторым Select, а третьим Where. Потому что linq основан на так называемых ленивых методах, с использованием лямбда-выражений. Это означает что метод будет работать не в строке ниже:

var result =students.Where(z => z.Group == "ПК-1").Select(z => z.LastName).ToList();

А когда мы воспользуемся перечислением в foreach и только тогда мы перейдем в метод ToList который является обычным методом, за тем Select, а из него в Where которые являются ленивыми методами, и так будет происходит по каждому элементу пока они не закончатся.

foreach (var name in result) 
Console.WriteLine(name);

Суть ленивых методов заключается в том, что один метод по элементно вызывает каждый раз другой, и в такой взаимосвязи они оба отрабатывают по каждому элементу. А вызов методов ленивых начинается с последнего метода, то есть с конца. Стоит запомнить что ленивые методы вызывают только обычные методы, сами они не будут отрабатывать, на то они и ленивые.

Как видите код программы сократился, при том что логика программа не большая, а понимание происходящего в коде программы стало проще, пошутил пока возможно вы еще ничего не поняли, но я объясню каждую команду. А вы сможете применять linq в своих приложениях.

Хочу показать еще пример классической реализации:

public List<int> GetLet()
{
	var resualt = new List<int>();
	for(int i=0; i<let.Length; i++)
	{
		if (let[i].IsNew)
			resualt.Add(let[i].Id);
	}
	return resualt;
}

И тот же пример с Linq:

public IEnumerable<int> GetLet()
{
	return let.Where(l => l.IsNew).Select(l => l.Id);
}

В Linq находиться интерфейс последовательности IEnumerable<T> Последовательность — это абстракция чего-то, что можно начать перечислять и переходить от текущего элемента к следующему пока последовательность не закончится (или не прервется принудительно).

Массивы, List, Dictionary, HashSet — все эти коллекции реализуют интерфейс последовательности IEnumerable<T>.

 

 

From так называемое предложение, указывает на источник данных, в лямбда-выражениях не используется.

 from student in faculty

 

Where Применяет фильтр, используется для фильтрации перечисляемого. Он принимает в качестве параметра функцию-предикат и возвращает новое перечисляемое, состоящее только из тех элементов исходного перечисляемого, на которых предикат вернул true, так же можно использовать  в запросе логические операторы.

where student.Name == "Andrey"
.Where(x => x.Length == words.Select(y => y.Length).Max()).First(); 
//находим максимальную длину массива слов

orderby Упорядочивание, сортирует или упорядочивает элементы возвращаемой последовательности к примеру по алфавиту:

От А до Я

orderby student.Name ascending
 mass = mass.OrderBy(worker => worker.Name).ToArray<Worker>();

mass= массив

worker = любое вымышленое название, которое будет использовано внутри выражения.

.Name свойство в классе Worker;

Worker =класс, с полями и методами.

 

От Я до А

orderby student.Name descending

group Группирования на основе ключа. Позволяет группировать, В примере ниже, я поместил всех Андреев в отдельную группу, и вывел их в консоль

static void Main()
		{

			string[] student = {"Andrey","Sergey,","Alexandr","Andrey","Dasha","Andrey","Kiril" };

			var searchStudent =
		    from cust in student
			group cust by cust.Equals("Andrey");

			
			foreach (var name in searchStudent)
			{
				if(name.Key)
				foreach (var customer in name)
				Console.WriteLine("    {0}", customer);
			}

			Console.ReadKey();
		}

Select  Задает тип возвращаемых элементов.

static void Main()
	{
		List<int> Scores = new List<int>() { 97, 92, 81, 60 };
		var queryHighScores =
		from score in Scores
		where score > 80
		select score;
		foreach (int i in queryHighScores)
		{
			Console.Write(i + " ");
		}
			
		Console.ReadKey();
	}

 

Выражение запроса должно оканчиваться предложением Select или group

Методы Linq:

Take обрезает последовательность после указанного количества элементов.

IEnumerable<T> Take(this IEnumerable<T> items, int count)

Skip обрезает последовательность, пропуская указанное количество элементов с начала.

IEnumerable<T> Skip(this IEnumerable<T> items, int count)

ToArray и ToList используются для преобразования IEnumerable<T> в массив T[] или в List<T>, соответственно.

static void Main()
	{
		int[] num = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		IEnumerable<int> even = num.Where(x => x % 2 == 0);
		IEnumerable<int> squares = even.Select(x => x * x);
		IEnumerable<int> squaresWithoutOne = squares.Skip(1);
		IEnumerable<int> secondAndThirdSquares = squaresWithoutOne.Take(2);
		int[] result = secondAndThirdSquares.ToArray();
		foreach (var i in result)
			Console.WriteLine(i);
			Console.ReadKey();
	}

 

Ключевые слова синтаксиса запроса:

from — Указание источника данных и переменной диапазона (аналогично переменной итерации).
where — Фильтрация исходных элементов на основе одного или нескольких логических выражений, разделенных операторами AND и OR ( && или || ).
select — Указание типа и формы, которую будут иметь элементы в возвращенной последовательности при выполнении запроса.
group — Группировка результатов запроса по заданному ключевому значению.
into — Предоставление идентификатора, который может служить ссылкой на результаты предложения join, group или select.
orderby — Сортировка результатов запроса по возрастанию или убыванию в компараторе по умолчанию для типа элемента.
join — Соединение двух источников данных на основе вычисления равенства между двумя заданными парными критериями.
let — Ввод переменной диапазона для хранения результатов вложенного выражения в выражении запроса.
in — Контекстно-зависимое ключевое слово в предложении join.
on — Контекстно-зависимое ключевое слово в предложении join.
equals — Контекстно-зависимое ключевое слово в предложении join.
by — Контекстно-зависимое ключевое слово в предложении group.
ascending — Контекстно-зависимое ключевое слово в предложении orderby.
descending — Контекстно-зависимое ключевое слово в предложении orderby.

 

Ключевые слова синтаксиса методов:

Объединение
Aggregate — Применяет к последовательности пользовательский метод.
Average — Вычисляет среднее для числовой последовательности.
Count — Возвращает количество элементов в последовательности (целочисленное значение).
LongCount — Возвращает количество элементов в последовательности (значение в диапазоне LongInt).
Min — Возвращает наименьшее значение для числовой последовательности.
Max — Возвращает наибольшее значение для числовой последовательности.
Sum — Складывает члены числовой последовательности.

Конкатенация
Concat — Соединяет две последовательности в одну.

Преобразование
Cast — Преобразует элементы последовательности в элемены указанного типа.
OfType — Выбирает из элементов последовательности элемены указанного типа.
ToArray — Возвращает массив из элементов последовательности.
ToDictionary — Возвращает словарь из элементов последовательности.
ToList — Возвращает список из элементов последовательности.
ToLookup — Возвращает результаты поиска по последовательности.
ToSequence — Возвращает последовательность IEnumerable.

Элемент
DefaultIfEmpty — Создает стандартный элемент для пустой последовательности.
ElementAt — Возвращает элемент последовательности по указанному индексу.
ElementAtOrDefault — Возвращает элемент по указанному индексу или стандартный элемент (если индекс вышел за пределы диапазона).
First — Возвращает первый элемент последовательности.
FirstOrDefault — Возвращает первый элемент последовательности или стандартный элемент (если нужный элемент не найден).
Last — Возвращает последний элемент последовательности.
LastOrDefault — Возвращает последний элемент последовательности или стандартный элемент (если нужный элемент не найден).
Single — Возвращает единственный элемент последовательности.
SingleOrDefault — Возвращает единственный элемент последовательности или стандартный элемент (если нужный элемент не найден).

Равенство
SequenceEqual — Проверяет эквивалентность двух последовательностей.

Создание
Empty — Создает пустую последовательность.
Range — Создает последовательность в соответствии с заданным диапазоном.
Repeat — Создает последовательность, повторяя значение заданное количество раз.

Группировка
GroupBy — Группирует элементы последовательности указанным образом.

Присоединение
GroupJoin — Выполняет группированное соединение двух последовательностей.
Join — Выполняет внутреннее соединение двух последовательностей.

Упорядочение
OrderBy — Упорядочивает элементы последовательности по заданным значениям в порядке возрастания.
OrderByDescending — Упорядочивает элементы последовательности по заданным значениям в порядке убывания.
ThenBy — Упорядочивает элементы уже упорядоченной последовательности в порядке возрастания.
ThenByDescending — Упорядочивает элементы уже упорядоченной последовательности в порядке убывания.
Reverse — Зеркально отображает порядок расположения элементов в последовательности.

Разделение на части
Skip — Возвращает последовательность, в которой указанное число элементов пропущено.
SkipWhile — Возвращает последовательность, в которой пропущены элементы, не соответствующие указанному условию.
Take — Возвращает последовательность, в которую включается указанное число элементов.
TakeWhile — Возвращает последовательность, в которую включаются элементы, соответствующие указанному условию.

Проекция
Select — Создает проекцию части последовательности.
SelectMany — Создает проекцию части последовательности по принципу «один ко многим».

Кванторы
All — Определяет соответствие всех элементов последовательности указанным условиям.
Any — Определяет, есть ли в последовательность элементы, удовлетворяющие указанным условиям.
Contains — Определяет, есть ли в последовательности указанный элемент.

Ограничение
Where — Сортирует члены последовательности.

Множества
Distinct — Возвращает последовательность без повторяющихся элементов.
Except — Возвращает последовательность, представляющую собой разность двух других последовательностей.
Intersect — Возвращает последовательность, представляющую собой пересечение двух других последовательностей.
Union — Возвращает последовательность, представляющую собой объединение двух других последовательностей.

 

Обновлено: 11.05.2018 — 12:48

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.