Лекция
Download
1 / 13

Итераторы и LINQ - PowerPoint PPT Presentation


  • 214 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Итераторы и LINQ' - kale


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Лекция

Итераторы и LINQ


Ienumerable ienumerator
Интерфейс 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> не обязательно подразумевает коллекцию.


Yield
Ключевое слово 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);


Примеры итераторов

Итератор может сам вырабатывать последовательность значений.

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;

}


Примеры итераторов

Итератор может основываться на двух входных последовательностях.

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);

}


Linq to objects
Что такое LINQ to Objects

  • Как показывают примеры, одни итераторы можно преобразовывать в другие итераторы, в числа, в массивы, вколлекцию, во что угодно.

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


Цепочечная композиция

Большинство преобразователей имеют форму методов, расширяющих тип 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));


Выражения запросов

От цепочечного выражения

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();


Пример выражения запроса

Выбрать из массива имен пятибуквенные имена и перевести их в верхний регистр.

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


Компиляция запросов

Компилятор переводит выражения запроса в цепочку вызовов расширяющих методов.

varquery = fromname in names

wherename.Length== 5

orderbyname

selectname.ToUpper();

varquery= names.Where (name=> name.Length== 5)

.OrderBy(name=> name)

.Select (name=> name.ToUpper());


Делегаты 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,…).


Where select
Запросы 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 );


Самостоятельно

  • Реализовать итератор, который позволит проходить любой целый массив в обратном порядке.

  • Реализовать обобщенный итератор, который позволит проходить любой массив в обратном порядке.

  • Сделать обобщенный итератор, который обходит двумерный массив по столбцам.

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

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


ad