Iterator

Acest articol poate conține lucrări nepublicate sau declarații neverificate (octombrie 2014).

Puteți ajuta adăugând referințe sau eliminând conținut nepublicat. Consultați pagina de discuții pentru mai multe detalii.

În inginerie software , The iterator este un model de proiectare (model de design) de comportament .

Un iterator este un obiect care vă permite să răsfoiți toate elementele conținute într-un alt obiect, cel mai adesea un container ( listă , copac etc.). Un sinonim pentru iterator este cursorul , mai ales în contextul bazelor de date .

Descriere

Un iterator arată ca un pointer cu esențial două primitive: accesarea elementului curent (în container) și deplasarea pentru a indica elementul următor. În plus, este necesar să puteți crea un iterator care indică primul element; precum și determinarea în orice moment dacă iteratorul a epuizat toate elementele din container. Diverse implementări pot oferi, de asemenea, comportamente suplimentare.

Scopul unui iterator este de a permite utilizatorului său să răsfoiască containerul, adică să acceseze secvențial toate elementele sale pentru a aplica procesarea acestora, izolând în același timp utilizatorul de structura internă a containerului., Potențial complex. Deci, containerul poate stoca articolele oricum doresc, permițând în același timp utilizatorului să le trateze ca pe o listă simplă. Cel mai adesea iteratorul este proiectat în același timp cu clasa de containere pe care va trebui să o parcurgă și va fi containerul în sine care va crea și distribui iteratorii pentru a accesa elementele sale.

Diferențe cu indexarea

În limbajele de procedură, un index este adesea utilizat într-o buclă simplă , pentru a accesa secvențial toate elementele, în special o matrice. Deși această abordare este încă posibilă în programarea obiectelor pentru unele containere, utilizarea iteratorilor are anumite avantaje:

Posibilitatea ca un container să fie modificat în timpul unei iterații a devenit necesară în programarea obiectelor moderne, în care relațiile dintre obiecte și efectul anumitor operații pot deveni o durere de cap. Prin utilizarea unui astfel de iterator „robust”, ne scutim de aceste inconveniente.

Folosind un iterator explicit

Într-un limbaj orientat obiect cum ar fi C #, un iterator este un obiect care implementează interfața IEnumerator.

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

Folosim iteratorul pentru a accesa valorile disponibile.

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

Una dintre numeroasele implementări de obiecte posibile ar putea arăta astfel.

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]; } } }

Interfața IEnumerableC # permite trecerea la un iterator implicit.

interface IEnumerable { IEnumerator GetEnumerator(); }

Tablourile C #, listele sau dicționarele sunt tipuri derivate din IEnumerableși au o metodă GetEnumerator()care apelează iteratorul explicit.

Declarația foreach a lui C # apelează această metodă GetEnumerator()și iterează explicit în timp ce ascunde detaliile implementării.

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

Iteratori implicați

Limbile orientate obiect, cum ar fi Perl și Python, oferă o modalitate „internă” de a itera elementele unui container fără a introduce în mod explicit un iterator. Acest lucru este adesea implementat de o structură de control pentru fiecare , ca în următoarele exemple:

# 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

Aveți grijă, în Javascript, nu repetăm ​​direct obiectele, ci numele lor

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

Limbajul C ++ are și funcția șablon std::for_each()care permite iterații implicite similare, dar necesită totuși furnizarea de obiecte iteratoare ca parametri de intrare.

Notă  : Ruby, Python și C # din versiunea 2.0, oferă prin intermediul yieldunui instrument specific pentru a construi iteratori.

Limbajul PHP implementează iteratori de la versiunea 5 prin SPL .