Итератор () е поведенчески шаблон за дизайн, който се използва в обектно-ориентираното програмиране. Итераторът предоставя начин за последователен достъп до елементите на обект, без да е нужна вътрешна информация за обекта. В компютърно програмиране, итератор е обект, който дава възможност на програмиста да преминава през структура от данни. Различни видове итератори често са предоставяни чрез интерфейс контейнер. Въпреки че интерфейсът и семантиката на даден итератор са фиксирани, итераторите често се прилагат по отношение на свързаните с тях структури за изпълнение и често са плътно свързани към контейнера, за да отговарят на семантиката на Итератора. Трябва да се има предвид, че итераторът чете и също така дава достъп до елементите в една структура от данни, но не изпълнява итерация (при тривиално използване на терминологията). Итераторът поведенчески е подобен на курсора на база данни.

Външни итератори и модела итератор Външно итераторът може да се представи като тип указател, който има две основни операции: Съотнасяне на един конкретен елемент в колекцията на обект и самото му модифициране така, че да сочи към следващия елемент.

В зависимост от езика и предназначението, итераторите могат също да предоставят допълнителни операции или да притежават различни поведения.

Основната цел на итератора е да позволи на потребителя да обработва всеки елемент на структурата от данни, докато изолира потребителя от вътрешната им структура. Итераторният клас обикновено е проектиран в тясно координиране със съответния клас на контейнера. Обикновено, класът-структура от данни осигурява методи за създаване на итератори.

Генератори Един от начините за прилагане на итератори е да се използва ограничена форма на coroutine, известна като генератор. За разлика от подпрограма, генераторът може да извика една стойност няколко пъти, вместо само веднъж.

Пример за генератор в Phyton, който връща итератор за номерата на Фибоначи: def fibonacci(limit): a, b, c = 0, 1, 0 while c < limit: yield a a, b, c = b, a+b, c+1

for number in fibonacci(100): # The generator constructs an iterator print(number)

Косвени Итератори Някои обектно-ориентирани езици като C#, C++ (по-нови версии), Delphi (по-нови версии), Go, Java (по-нови версии), Lua, Perl, Python, Ruby предоставят присъщ начин за итериране през елементите на структура от данни без въвеждането на изричен итератор. Итератор действително може да съществува, но ако е така той не е изложен в програмния код.

Косвените итератори най-често се изразяват чрез цикъла "foreach" (или еквивалентен), като в следващия пример на Python: for value in iterable: print value

В Python "iterable" е обект, към който може да се прикачи итератор, който след това се повтаря по време на цикъл. Или в други случаи, те могат да бъдат създадени от самия обект, като в този Ruby код: iterable.each do |value|   puts value end

Потоци Итераторите са полезна абстракция на входящите потоци – те предоставят потенциално безкрайно повтаряне на обект. Няколко езика, като Perl и Python, прилагат потоци като итератори. Алтернативни реализации на поток включват data-drivenезици, като AWK.

Класифициране на итератори Категории Итераторите могат да бъдат категоризирани в зависимост от тяхната функционалност. Ето един (неизчерпателен) списък на категории: Категория Език Bidirectional iterator C++ Forward iterator C++ Input iterator C++ Output iterator C++ Random access iterator C++ Trivial iterator C++ (old STL)

Видове Различни езици или библиотеки, използвани с тези езици определят вида итератор. Някои от тях са: Вид Език Array iterator PHP, R Caching iterator PHP Constant iterator C++, PHP Directory iterator PHP, Python Filter iterator PHP, R Limit iterator PHP List iterator Java, R Recursive array iterator PHP XML iterator PHP

Примери C++ Езикът C++ имплементира широкото използване на итератори в своята Стандартната библиотека, която осигурява достъп до няколко различни видове итератори, включително препращащи итератори, двупосочни итератори и итератори с произволен достъп. Всички стандартни видове шаблонни контейнери предоставят богат и последователен набор от видове итератори. Синтаксисът на стандартните итератори е проектиран да наподобява този на стандартната C аритметиката с указатели, като операторите ‘*’ и ‘->’ се използват за показване на елемента, към който итераторът сочи.

C# Итераторите обикновено се използват, чрез извикване на метода GetEnumerator () на обекта за изпълнение на IEnumerable интерфейса. Класове-контейнери обикновено въвеждат този интерфейс, въпреки това foreach твърдението в C# може да работи с всеки обект, който предоставя такъв метод, дори ако той не се изпълни от IEnumerable. Следните примери показва използването на итератори в C #: // explicit version IEnumerator<MyType> iter = list.GetEnumerator(); while (iter.MoveNext()) Console.WriteLine(iter.Current);

// implicit version foreach (MyType value in list) Console.WriteLine(value);

Java Представен в Java JDK 1.2 издание, "java.util.Iterator" интерфейсът позволява итериране на класове. Всеки итератор осигурява "next()" и "hasNext()" метод и може да поддържа "remove()" метод. Итераторите са създадени от съответните съдържащи класове, обичайно от метод наречен "iterator()". Методът "next()" преминава през итератора и връща стойността посочена от итератора. Първият елемент е получен при първото извинкване на следващ "next()". За да се определи кога всички елементи в контейнера са били посетени се използва "hasNext()" метода.

Следващият пример показва проста употреба на итератори: Iterator iter = list.iterator(); //Iterator<MyType> iter = list.iterator(); in J2SE 5.0 while (iter.hasNext()) {     System.out.print(iter.next());     if (iter.hasNext())       System.out.print(", ");

Scala В Scala, итератори имат богат набор от методи, подобни на колекции, и могат да бъдат използвани директно в for цикли. Всъщност, както итераторите, така и колекциите наследяват от общите черти на – scala.collection.TraversableOnce. Въпреки това, заради богатият набор от методи, които съществуват в Scala колекциите, като например map, collect, filter и т.н., то не се налага често да боравим с итератори директно при програмирането в Scala.

Java итератори и колекции могат автоматично да бъдат превърнати в Scala итератори и колекции, просто чрез добавяне на един-единствен ред

import scala.collection.JavaConversions към файла. Обектът JavaConversions осигурява имплицитни превръщания. Косвените преобразувания са характерни за Scala: методи, които, когато са видими в текущия обхват, автоматично се извикват в най-подходящото място, за да се typecheck-нат когато те иначе не биха.

PHP PHP 4 въведе foreach конструкцията, подобно на Perl и някои други езици. Това просто дава лесен начин за обхождане на масиви. foreach работи само върху масиви в PHP 4, и ще изведе грешка, когато се опитате да го използвате на променлива с различен тип данни или неинициализирана променлива. В PHP 5, foreach е позволено за итериране върху обект през всички публични членове.

Има два синтаксиса; Вторият е незначително, но полезно разширение на първият.

Пример A

foreach (array_expression as $value) { echo "$value\n"; }

Пример Б

foreach (array_expression as $key => $value) { echo "($key)$value\n"; }

В Пример А итерираме върху масива обозначен с array_expression. На всяко завъртане на цикъла стойността на текущия елемент се записва в $value и вътрешният указател на масива се увеличава с единица (така, че при следващо завъртане на цикъла ще гледа към следващия елемент).

В Пример Б имаме същата функционалност като в Пример А. В допълнение текущият ключ на елемента (в нашият случай array_expression) ще бъде записан в променливата $key при всяко завъртане на цикъла.

Интерфейсът на итератора е предефиниран в PHP 5 и обектите могат да бъдат персонализирани, за да се справят с итерацията.

class MyIterator implements Iterator {     private $var = array();

    public function __construct($array) {         if (is_array($array)) { $this->var = $array;

    public function rewind() {         echo "rewinding\n";         reset($this->var);

    public function current() {         $var = current($this->var);         echo "current: $var\n";         return $var;

    public function key() {         $var = key($this->var);         echo "key: $var\n";         return $var;

    public function next() {         $var = next($this->var);         echo "next: $var\n";         return $var;

    public function valid() {         $var = $this->current() !== false;         echo "valid: {$var}\n";         return $var;

Тези методи биват използвани в пълна foreach($obj AS $key=>$value)последователност. Методите на итераторите се изпълняват в следния ред:

1. rewind() 2. while valid() {        2.1 current() in $value        2.3 key() in $key        2.4 next()

Python Итераторите в Python са основна част от езика, а и в много случаи са невидими тъй като по презумпция се използва в for (foreach) декларация, в list comprehensions, и в generator expressions. Всички стандартно вградени видове колекции в Пайтън поддържат итерация, както и много класове, които са част от стандартната библиотека. Следващият пример показва типична имплицитна итерация върху последователност:

for value in sequence:

print (value)

Python речниците (форма на асоциативен масив) също могат да бъдат директно итерирани, когато ключовете на речника се връщат; или метода items на речник може да се итерира отново, където той получава съответната ключ, стойност двойка като кортеж: for key in dictionary: value = dictionary[key] print(key, value)

for key, value in dictionary.items(): print(key, value) Итераторите могат да се използват и дефинират изрично. За всеки тип итерираща последователност или клас, вградената функция iter () се използва за създаване на итератор обект. Итериращият обект може след това да се итерира с функцията next(), която използва вътрешно метода __next __ (), който връща следващия елемент в контейнера. (Предишното изявление се отнася за Python 3.x. В Python 2.x, метода next() е еквивалентен.). Ще възникне StopIteration exception, когато не са останали повече елементи. Следващият пример показва еквивалентна итерация върху последователност използвайки експлицитни итератори: it = iter(sequence) while True: try: value = it.next() # in Python 2.x value = next(it) # in Python 3.x except StopIteration: break it = iter(it) print(value)

Източници

Външни препратки Java's Iterator, Iterable and ListIterator Explained .NET interface Iterators Boost C++ Iterator Library Java interface PHP: Object Iteration STL Iterators What are iterators? - Reference description

Категория:Шаблони за софтуерен дизайн