Iterátor

Tento článek může obsahovat nepublikovanou práci nebo neověřená prohlášení (října 2014).

Můžete pomoci přidáním odkazů nebo odebráním nepublikovaného obsahu. Další podrobnosti najdete na diskusní stránce .

V softwarovém inženýrství je iterátor je návrhový vzor (návrhový vzor) chování .

Iterátor je objekt, který umožňuje procházet všechny prvky obsažené v jiném objektu, nejčastěji kontejner ( seznam , strom atd.). Synonymem pro iterátor je kurzor , zejména v kontextu databází .

Popis

Iterátor vypadá jako ukazatel se v zásadě dvěma primitivy: přístup k aktuálnímu špičatému prvku (v kontejneru) a přesunutí tak, aby ukazovalo na další prvek. Kromě toho je nutné mít možnost vytvořit iterátor ukazující na první prvek; a také kdykoli zjistit, zda iterátor vyčerpal všechny prvky v kontejneru. Různé implementace mohou také nabídnout další chování.

Cílem iterátoru je umožnit jeho uživateli procházet kontejner, to znamená sekvenčně přistupovat ke všem jeho prvkům a aplikovat na ně zpracování, zatímco izoluje uživatele od vnitřní struktury kontejneru., Potenciálně složitý. Kontejner tedy může ukládat položky, jak chtějí, a přitom uživateli umožnit, aby s ním zacházelo jako s jednoduchým seznamem. Nejčastěji je iterátor navržen současně s třídou kontejneru, kterou bude muset procházet, a bude to samotný kontejner, který vytvoří a distribuuje iterátory pro přístup k jeho prvkům.

Rozdíly s indexováním

V procedurálních jazycích se index často používá v jednoduché smyčce pro postupný přístup ke všem prvkům, zejména k poli. I když je tento přístup v programování objektů pro některé kontejnery stále možný , použití iterátorů má určité výhody:

Možnost úpravy kontejneru během iterace se stala nezbytnou v moderním programování objektů , kde se vztahy mezi objekty a účinek určitých operací mohou stát bolestí hlavy. Použitím takového „robustního“ iterátoru jsme ušetřeni těchto nepříjemností.

Použití explicitního iterátoru

V objektově orientovaném jazyce, jako je C #, je iterátor objekt, který implementuje rozhraní IEnumerator.

interface IEnumerator { void Reset(); bool MoveNext(); object Current { get; } }

Pro přístup k dostupným hodnotám používáme iterátor.

IterateurTypique iterateur = new IterateurTypique(); iterateur.Reset(); // optionnel : cet appel peut ne pas être effectué. while(iterateur.MoveNext()){ Console.WriteLine(iterateur.Current); }

Jedna z mnoha možných implementací objektů může vypadat takto.

class IterateurTypique : IEnumerator { private string[] _chainesAParcourir = new string[] { "TF1", "France2", "FR3", "Canal+" }; private int _positionCourante = -1; public void Reset() { _positionCourante = -1; } public bool MoveNext() { if( _positionCourante + 1 >= _chainesAParcourir.Length ) return false; _positionCourante +=1; return true; } public object Current { get { return _chainesAParcourir[_positionCourante]; } } }

Rozhraní IEnumerableC # umožňuje přepnutí na implicitní iterátor.

interface IEnumerable { IEnumerator GetEnumerator(); }

C # pole, seznamy nebo slovníky jsou typy odvozené od IEnumerablea mají metodu, GetEnumerator()která volá explicitní iterátor.

Příkaz foreach GetEnumerator()jazyka C # volá tuto metodu a explicitně iteruje, zatímco skrývá podrobnosti implementace.

if(Television is IEnumerable) { foreach(object chaine in Television) { Console.WriteLine(chaine); } }

Implicitní iterátory

Objektově orientované jazyky jako Perl a Python poskytují „interní“ způsob iterace přes prvky kontejneru, aniž by výslovně představovaly iterátor. To je často implementováno strukturou řízení pro každý , jako v následujících příkladech:

# Tcl: itérateur implicite foreach val $list { puts stdout $val } # Perl: itérateur implicite foreach $val (@list) { print "$val\n"; } # Python, itérateur implicite for Value in List: print Value // PHP, itérateur implicite foreach ($list as $value) print $value; // Java, J2SE 5.0, itérateur implicite for (Value v : list) System.out.print(v); // C#, itérateur implicite foreach (object obj in list) Console.WriteLine(obj ); // C#, itérateur explicite avec un yield foreach (object obj in IndicesPairs() ) Console.WriteLine(obj); // ou IndicesPairs() est une méthode IEnumerable IndicesPairs() { for(int i=0; i<tableau.Length; i++) if(i%2==0) yield return tableau[i]; } # Ruby, itérateur de bloc, (yield) list.each do |value| puts value end # ou each est une méthode de Array tel que : def each for i in 0...size yield(self[i]) end end

Pozor, v Javascriptu ne iterujeme přímo na objekty, ale na jejich jméno

// Javascript, itérateur implicite for(nom in Object) { var valeur = Object[nom]; alert(Value+" = "+valeur ]); }

Jazyk C ++ má také funkci šablony, std::for_each()která umožňuje podobné implicitní iterace, ale stále vyžaduje poskytnutí iterátorových objektů jako vstupních parametrů.

Poznámka  : Ruby, Python a C # od verze 2.0 nabízejí prostřednictvím yieldkonkrétního nástroje pro vytváření iterátorů.

Jazyk PHP implementuje iterátory od verze 5 prostřednictvím SPL .