1 / 13

Итераторы и LINQ

Лекция. Итераторы и LINQ. Интерфейс IEnumerable и IEnumerator. Любая коллекция реализует интерфейс IEnumerable. public interface IEnumerable < out T> : IEnumerable { IEnumerator <T> GetEnumerator (); }.

kale
Download Presentation

Итераторы и LINQ

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Лекция Итераторы и LINQ

  2. Интерфейс IEnumerable и IEnumerator Любая коллекция реализует интерфейс IEnumerable. publicinterfaceIEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } Объект, возвращаемый методом GetEnumerator(),называется итератор. Итератор реализует интерфейсIEnumerator<T>: publicinterfaceIEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } boolMoveNext(); // false, когда дальше ехать некуда void Reset(); } Замечание. Интерфейс IEnumerator<T> не обязательно подразумевает коллекцию.

  3. Ключевое слово yield Главным в интерфейсе IEnumerator<T> является метод MoveNext(), поэтому итератор можно объявить, запрограммировав только его, остальное компилятор доделает сам. Для этого в С# существует слово yield. IEnumerator<int> Iter() { yieldreturn 1; yieldreturn 2; yieldreturn 3; } for (variter = Iter(); iter.MoveNext(); ) Console.WriteLine(iter.Current); Если возвратить не IEnumerator<T> а IEnumerable<T>, то компилятор создаст боле удобный в использовании объект. • IEnumerable<int> Iter() { yieldreturn 1; yieldreturn 2; yieldreturn 3; } foreach (var i inIter()) Console.WriteLine(i);

  4. Примеры итераторов Итератор может сам вырабатывать последовательность значений. staticIEnumerable<int> Range(int a, int b) { for (int i = a; i < b; i++) yieldreturni; } Итератор может основываться на входной последовательности. staticIEnumerable<int> Filter(IEnumerable<int> it) { foreach (var x in it) if (x % 2 == 0) yieldreturn x; }

  5. Примеры итераторов Итератор может основываться на двух входных последовательностях. staticIEnumerable<Point> Decart(IEnumerable<int> a, IEnumerable<int> b) { foreach (var x in a) foreach (var y in b) yieldreturnnewPoint(x, y); } или на любом количестве входных последовательностей. staticIEnumerable<int> Maximes(paramsIEnumerable<int>[] xs) { foreach (var x in xs) yieldreturn Max(x); }

  6. Что такое LINQ to Objects • Как показывают примеры, одни итераторы можно преобразовывать в другие итераторы, в числа, в массивы, вколлекцию, во что угодно. • Набор готовых методов-преобразователей, который содержится в статическом классе System.Linq.Enumerable, и составляет основное содержание LINQ to Objects.

  7. Цепочечная композиция Большинство преобразователей имеют форму методов, расширяющих тип IEnumerable<T>, например, • publicstaticint Count<TSource>(thisIEnumerable<TSource> source); Композицию таких методов можно записать так. • int n = Enumerable.Range(1, 10).Where(x => x % 2 == 0).Count(); Для сравнения – композиция, записанная обычным способом. Enumerable.Count(Enumerable.Where(Enumerable.Range(1, 10), x => x % 2 == 0));

  8. Выражения запросов От цепочечного выражения int n = Enumerable.Range(1, 10) .Where(x => x % 2 == 0) .Count(); один шаг до выражения запроса. var v = from x inEnumerable.Range(1, 10) where x % 2 == 0 select x; int n = v.Count();

  9. Пример выражения запроса Выбрать из массива имен пятибуквенные имена и перевести их в верхний регистр. usingSystem; usingSystem.Linq; usingSystem.Collections.Generic; classProgram { staticvoid Main() { string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David"}; varquery = fromnameinnames wherename.Length == 5 orderbyname selectname.ToUpper(); foreach (string item in query) Console.WriteLine(item); } } BURKE DAVID FRANK

  10. Компиляция запросов Компилятор переводит выражения запроса в цепочку вызовов расширяющих методов. varquery = fromname in names wherename.Length== 5 orderbyname selectname.ToUpper(); varquery= names.Where (name=> name.Length== 5) .OrderBy(name=> name) .Select (name=> name.ToUpper());

  11. Делегаты Func Чтобы объявить метод LINQ, с параметром-делегатом, нужно указать тип параметра. publicstaticIEnumerable<TSource> Where<TSource> (thisIEnumerable<TSource> source, Func<TSource, bool> predicate); Для указания типа параметров используются обобщенный делегат Func, объявленный в пространстве имен System. publicdelegateTResultFunc<in T, outTResult>(T arg); Делегат перегружен и может принимать от 0 до 16 входных параметров-типов (T1, T2, T3,…).

  12. Запросы Where() и Select() Where() – фильтр Пример: оставить только четные числа IEnumerable<int> result = m.Where(a => a % 2 == 0); Пример: оставить только числа, стоящие на четных местах IEnumerable<int> result = m.Where((a, i) => i % 2 == 0); Select() – проекция Пример:увеличить все числа в 1000 раз IEnumerable<int> result = m.Select(a => a * 1000 ); И оба вместе: varresult = m.Where(a => a % 2 == 0).Select(a => a * 1000 );

  13. Самостоятельно • Реализовать итератор, который позволит проходить любой целый массив в обратном порядке. • Реализовать обобщенный итератор, который позволит проходить любой массив в обратном порядке. • Сделать обобщенный итератор, который обходит двумерный массив по столбцам. • Объявить итератор, который получает один целочисленный массив в качестве аргумента и вырабатывает все уникальные значения из входного массива. { 2, 3, 4, 3 ,3, 1 ,2 } => {2, 3, 4, 1} • Объявить итератор, который получает два целочисленных массива в качестве аргументов и вырабатывает только те значения, которые есть в первом массиве и в то же время отсутствуют во втором массиве. {1, 2, 3, 5, 6}, {4, 5, 1 } => {2, 3, 6}

More Related