Iterator

Izvor: Wikipedija
Prijeđi na navigaciju Prijeđi na pretragu

U programiranju, iterator je objekat koji omogućuje programeru da prolazi kroz kolekciju, naročito listu.[1][2][3] Različite interfejsne kolekcije često pružaju različite vrste iteratora. Iako su interfejs i semantika datog iteratora fiksne, iteratori se često implementirani u vidu struktura koje su osnovi kolekcije i često su čvrsto povezani sa kolekcijom da bi se omogućila operativna semantika iteratora. Traba imati na umu da iterator vrši prelazak i takođe daje pristup elementima kolekcije, ali ne izvršava ponavljanje (tj, ne bez nekog značajnog oduzimanja slobode tog koncepta ili sa trivijalnim korišćenjem tehnologije). Iterator je po ponašanju sličan kursoru baze podataka. Iteratori datiraju još od CLU programskog jezika iz 1974.

Opis[uredi | uredi kod]

Eksterni iteratori i šablon iteratora[uredi | uredi kod]

Spoljašnji iterator se može razmatrati kao tip pokazivača koji ima dve primarne operacije: upućuje na jedan poseban element u kolekciji objekata (zove se pristup elementu) i  dopuna sebe tako da ukazuje na sledeći element (zove se prolaz elementa).[4] Takođe mora postojati način da se stvori iterator tako da ukazuje na neki prvi element kao i način da se odredi kada će iterator istrošiti sve elemente kolekcije. U zavisnosti od jezika i namene, iteratori mogu omogućiti dodatne operacije ili pokazati različita ponašanja.

Primarna svrha iteratora je da dozvoli korisniku da izvrši proces nad svakim elementom kolekcije dok izoluje korisnika od unutrašnje strukture kolekcije.[2] Ovo omogućava sadržini da skladišti elementi na bilo koji način dok dozvoljava korisniku da ih tretira kao da su sekvenca ili lista. Klasa iteratora je uglavnom dizajnirana u tesnoj saradnji sa klasom kolekcije. Obično, kolekcija omogućava metode za kreiranje iteratora

Imati na umu da se brojač petlje takođe naziva i iterator petlje. Brojač petlje, međutim, samo omogućava prolaz funkcionalnosti i nefunkcionalnost pristupa elementa.

Generatori[uredi | uredi kod]

Jedan način implementacije iteratora je korišćenje ograničenog oblika nadprograma, poznatog kao generator. Suprotno njemu je potprogram, generator nadprograma može preuzeti vrednosti njegovog pozivača nekoliko puta, umesto da ih vraća. Većina iteratora su prirodno izraziti kao generatori, ali pošto generatori čuvaju svoju lokalnu naredbu između priziva, oni su posebno dobro opremljeni za komplikovane, naredbene iteratore, kao obilazak stabla. Postoje suptilne razlike i odlike u korišćenju termina "generator" i "iterator", koji veriraju između autora i jezika.[2] U Pajtonu, generator je konstruktor iteratora: funkcija koja vraća iterator. Primer Pajtonovog generatora koji vraća iterator su Fibonačijevi brojevi koji koriste Pajtonovuyield naredbu:

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): # Generator konstruiše iterator
    print(number)

Implicitni iteratori[uredi | uredi kod]

Neki objektno-orijentisani jezici kao što su C#, C++ (ranije verzije), Delphi (ranije verzije), Gou, Java (ranije verzije), Lua, Perl, Pajton, Rubi pružaju suštinski način ponavljanja kroz elemente sadržine objekta bez upoznavanja sa objektnim eksplicitnim iteratorom. Stvarni iterator može postojati u realnosti, ali ako se to desi on nije eksponiran izvornom kodu jezika.[4][5]

Implicitni iteratoru se često manifestuju "forič" izjavom (ili ekvivaletno), kao što je sledeći primer u Pajtonu: 

for value in iterable:
    print value

U Pajtonu, iterabla je objekat koji može biti konvertovan u iterator, koji je kasnije ponavljan tokom for petlje; ovo se dešava implicitno. Ili drugi put mogu biti kreirane same od sebe zbirkom objekata, kao u ovom primeru kod Rubija:

iterable.each do |value|
  puts value
end

Ovaj stil ponavljanja se ponekad naziva i "interno ponavljanje" zato što se njegov kod potpuno izvršava unutar konteksta objekta (to kontroliše sve aspekta ponavljanja), i programer samo omogućava operaciju da se izvrši svakog koraka (koristeći anonimnu funkciju). Jezici koji podržavaju listu shvatanja ili sličnih konstrukcija mogu takođe koristiti implicitne iteratore tokom konstrukcije liste rezultata, kao u Pajtonu:

names = [person.name for person in roster if person.male]

Ponekad je implicitna priroda sakrivena delimično. S++ jezik ima nekoliko funkcionalnih šablona za implicitno ponavljanje, kao što je for_each(). Ove funkcije idalje zahtevaju eksplicitan objekat iteratora kao njihov prvi ulaz, ali kasnije ponavljanje ne izlaže objekat iteratora korisnikuT

Potoci[uredi | uredi kod]

Iteratori su korisna abstrakcija ulaznih tokova- oni obezbeđuju potencijalnu beskonačan iterabilni (ali ne nužno izmenlji) objekat. Nekoliko jezika, kao što je Perl i Pajton, sprovode potoke kao iteratore. Alternativne implementacije potoka uključuju podatke-vođene jezika, kao što su AWK i sed.

Razlike sa indeksima[uredi | uredi kod]

U postupnim jezicima često se koriste podskripni operatori i brojač petlje da bi se petljalo kroz sve elemente u sekvenci kao što je niz. Iako indeksovanje se može takođe koristiti sa nekom objektno-orijentisanom sadržinom, korišćenje iteratora može imati prednosti:[6]

  • Brojanje petlji ne odgovara svim strukturama podataka, posebno strukture podataka sa ili bez nasumičnog pristupa podataka, kao što su liste i stabla.
  • Iteratori mogu omogućiti dosledan način da ponove nad strukturom podataka svih vrsta, a sammim tim da naprave kod čitljivijim, za višekratnu upotrebu, i manje osetljiv na promene u strukturi podataka. 
  • Iterator može nametnuti dodatna ograničenja na pristup, kao što je obezbeđenje da elementi ne mogu biti preskočeni ili da prethodno posećeni elementi ne mogu imati pristup drugi put.
  • Iterator može dozovliti objektu sadržine da bude izmenjen bez poništavanja iteratora. Na primer, kada je iterator napredovao dalje od prvog elementa moguće je uneti dodatne elemente na početak sadržine sa predvidivim rezultatima. Sa indeksovanjem ovo je problematično pošto se brojevi indeksa moraju menjati.

Mogućnost sadržine da bude promenljiva dok se ponavlja kroz njene elemente je postala neophodna u objektno-orijentisanom programiranju, gde su međusobni odnosi između objekata i efekat operacija ne može biti očigledan. Krošćenjem iteratora jedan je izolovan od ovih posledica. Ova tvrdnja, međutim, mora se uzeti sa rezervom, jer je češće nego ne, iz efikasnih razloga, implementacija iteratora je tesno povezana za sadržinu koji ne sprečava izmenu osnovne sadržine bez poništavanja sebe.

Za sadržine koje se mogu kretari kroz njihove podatke u memoriji, jedini način da ne ponište iterator je, za sadržinu, da nekako prati kretanje svih trenutno živih iteratora i ažurira ih u hodu. Pošto broj iteratora u datom trenutku može biti proizvoljno veliki u odnosu na veličinu vezane sadržine, ažuriranjem svih njih će drastično uticati na složenost garancije operacija sadržine.

Alternativni način da se zadrži broj ispravki vezanih u odnosu na veličinu sadržine bi bio da se koristi neka vrsta mehanizma ručki, to je kolekcija indirektnih pokazivača elemenata sadržine koja mora biti ažurirana sa sadržinom, i da dopusti pokazivaču iteratora ovim ručkama  direktno elementima podataka. Ali ovaj pristup će negativno uticati na performans iteratora, jer on mora ostvariti dupli pokazivač prateći pristup stvarnom elementu podataka. Ovo obično nije poželjno, zato što mnogi algoritmi koriste iteratore da pozovu pristup podataka iteratora češće nego metodu unapred. Zato je posebno važno imati iteratore sa veoma efikasnim pristupom podacima.

Sve u svemu, ovo je uvek kompromis između sigurnosti (iteratori ostalu uvek validni) i efikasnosti. Većinu vremena, dodata sigurnost nije vredna cene efikanosti za plaćanje. Koristeći alternativnu sadržinu (na primer jednostruka povezana lista umesto vektora) bi bio bolji izbor (globalno efikasnije) ako je stabilnost iteratora potrebna.

Klasifikovanje iteratora[uredi | uredi kod]

Kategorije iteratora[uredi | uredi kod]

Iteratori mogu biti kategorizovani po njihovoj funkcionalnosti. Ovde je (ne-konačna) lista kategorija iteratora:[7][7]

Kategorija Jezici
Dvosmerni iterator C++
Napredni iterator C++
Ulazni iterator C++
Izlazni iterator C++
Standarna biblioteka šablona C++
Trivijalni iterator C++ (stariji STL)[8]

Tipovi iteratora[uredi | uredi kod]

Različiti jezici ili biblioteke korišćene ovim jezicima definišu tipove iteratora. Neki od njih su:[7]

Type Languages
Iterator niza PHP, R[9]
Hvatajući iterator PHP
Iterator konstante C++,[10] PHP
Interator direktorijuma PHP, Pajton
Iterator filtera PHP, R
Iterator ograničenja PHP
Iterator liste Java,[11] R
 Iterator rekurzivnog niza PHP
XML iterator PHP

U različitim programskim jezicima[uredi | uredi kod]

C# i ostali .NET jezici[uredi | uredi kod]

Iteratoru u  . NET Framework se zovu "popisivači" i i predstavljaju se pomoću IEnumerator interfesa. IEnumerator omogućuje MoveNext() metodu, koja se plasira u naredni element i ukazuje da je postignut kraj zbirke ;  Current vlasništvo, da bi se dobila vrednost elementa trenutno ukazanog; i opcionalnatReset() metoda, da se premota popisivač nazad na njegovu početnu poziciju. Popisivač u početku pozakuje specijalnu vrednost pre prvog elementa, tako da poziv na MoveNext() je tražen kako bi počelo ponavljanje.

Popisivači se obično dobijaju pozivom na GetEnumerator() metodu objekata koji se sprovodi nad IEnumerable interfejsom. Klase sadržine obično sprovode ovaj interfejs. Međutim, forič izjava u  C#  mogu da rade na bilo kom objektu koji pruža takvu metodu, čak i ako se ne sprovodi IEnumerable. Oba interfejsa su se proširila na generičke verzije u  . NET 2.0.

U nastavku sledi korišćenje iteratora u C# 2.0:

// eksplicitna verzija
IEnumerator<MyType> iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

// implicitna verzija
foreach (MyType value in list)
    Console.WriteLine(value);

C# 2.0 takođe podržava generatore: meroda koja je deklarisana kao povratna IEnumerator (ili IEnumerable), ali koristi "yield return" izjavu da proizvede niz elemenata umest da vraća instancu objekata, će biti transformisan od strane kompajlera u novu klasu sprovodeći odgovarajući interfejs.

C++[uredi | uredi kod]

C++ jezik pravi širok spektar iteratora u njegovoj Standardnoj Biblioteci Šablona, koja omogućuje nekoliko različitih iteratora, uključujući napredni iterator, bidirekcioni iterator, i standardnu biblioteku iteratora. Sve vrste standardnih konteinera  pružaju bogat i dosledan skup tipova iteratora. Sintaksa standardnih iteratora je dizajnirana da podseća na obične  C aritmetičke pokazivače, gde * i -> operatori se koriste kao referenca elementa koji iterator pokazuje, i aritmetički pokazivači operatora kao što je ++ se korsite da unaprede iterator na sledeći nivo.

Iteratori se obično koriste u parovima, gde se jedan koristi za ponavljanje i drugi služi da obeleži kraj zbirke. Iteratori su napravljeni od strane odgovarajuće klase sadržine koristeći se standardnim metodama kao sto su  begin() i end(). Iteratore vraćen od begin() pokazuje na prvi element , dok iterator vraćen od end() je specijalna vrednost koja pominje nikakav element. Kada je iterator napredovao iznad poslednjeg element on je po definiciji jednak specijalnom kraju vrednosti iteratora.

Sledeći primer pokazuje tipično korišćenje iteratora.

std::vector<int> items;
items.push_back(1); // Povećaj celobrojnu vrednost '1' na vektor 'stavki'
items.push_back(2); // Povećaj celobrojnu vrednost '2' na vektor 'stavki'
items.push_back(3); // Povećaj celobrojnu vrednost '3' na vektor 'stavki'

for (std::vector<int>::iterator i = items.begin(); i != items.end(); ++i) { // Iterate through 'items'
   std::cout << *i; // I štampaj vrednost od 'stavki' za trenutni indeks
}
//in C++11
for(auto i:items){
   std::cout << i; // I štampaj vrednost od 'stavki'
}
//

//Prints 123

Postoje mnogo sorti iteratora svaki sa malo različitim ponašanjem, uključujući: napred, nazad i biderkcione iteratora; standardna biblioteka šablona; ulazeći i izlazeći iteratori; i konstantni iteratori (koji štiti sadržinu ili njegove elemente od modifikacije). Međutim, ne podržava svaki tip sadržine svaki tip iteratora. Moguće je za korisnike da naprave svoj tip iteratora pomoću izvođenja podklase od standardnog  std::iterator šablona klase.

Bezbednost iteratora se definiše odvojeno za različite tipove standarnih sadržina, u nekim slučajevima iterator je veoma dopustiv u dozovli sadržine da se promeni dok ponavlja

Implicitna iteracije je delimično podržana od strane C++ kroz korišćenje standardnih funkcija šablona, kao što jet std::for_each(), std::copy() i std::accumulate().

Kada su korišćeni moraju biti pokrenuti sa postojećim iteratorom, obično begin i end, koji definišu opseg na kome se ponavljanje izvršava. Ali nijedan eksplicitni objekat iteratora nije izložen dok ponavljanje traje. Ovaj primer pokazuje korišćenje for_each.

ContainerType<ItemType> C; // Bilo koja standardna sadržina tipa ItemType elemenata

void ProcessItem(const ItemType& I) { // Funkcija koja će procesofati svaku stavku zbrike
   std::cout << I << std::endl;
}

std::for_each(C.begin(), C.end(), ProcessItem); // For-ič iteracija petlje

Isto se može postići koristeći std::copy i std::ostream_iterator

std::copy(C.begin(), C.end(), std::ostream_iterator<ItemType>(std::cout, "\n"));

Ograničenje je to da ova tehnika ne dozvoljava telu forič petlje da bude deklarisana u redu, zahteva pokazivač funkcije ili objekat funkcije da bude deklarisan negde drugde i da prođe kao argument. Ovo se može delimično nadoknaditi koristeći zbirku kao što je Bust i koristeći lambdu da se implicitno generiše funkcija objekata sa poznatom umetnutom sintaksom operatora. Međutim, pošto se Bust sprovodi na nivou biblioteke, nego istinski u jeziku, neke stvari se moraju uraditi pomoći zaobilaznice. 

Trenutni standard C++, C++11, izvorno podržava lambda funkciju sintakse, što dozvoljava funkciji šablona tela da bude deklarisana u redu.

Ovde je primer forič ponavljanja koristeći lambda funkciju

ContainerType<ItemType> C; // Bilo koja standardna sadržina tipa ItemType elemenata

// For-ič iteracija petlje sa lambda funkcijom
std::for_each(C.begin(), C.end(), [](const ItemType& I){ std::cout << I << std::endl; });

Java[uredi | uredi kod]

Predstavljen u Javi JDK 1.2 izdanju, java.util.Iterator interfejs dozvoljava iteraciju sadržine klasa. Svaki  Iterator dajenext() ihasNext() metodu, a po izboru može podržatiremove() metodu. Iteratori su napravljeni pomoću odgovarajućih sadržina klase, tipično pomoću metode zvane iterator().[12]

 next() metoda unapređuje iterator i vraća vrednost pokazanu od strane iteratora. Prvi element dobijen na prvi zahtev next(). Da bi se odlučilo kada su svi elementi u sadržini su bili posećenihasNext() test metoda se koristi. Sledeći primer pokazuje jednostavnu upotrebu iteratora:

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(", ");
}

Da bi se pokazalo dahasNext() može biti pozvan nekoliko puta, koristima ga da ubacimo zapete između elemenata ali ne posle poslednjeg elementa.

Umajte na umu da ovaj pristup ne razdvaja pravilno naprednu operaciju od pravog pristupa podataka. Ako element podatak mora biti korišćen više od svakog naprednog, potrebno je da bude sačuvan u privremenoj promenljivoj. Kada je napredovanje potrebno bez pristupa podataka (tj. da se preskoči dati element podataka), pristup je ipak izveden, iako je vraćena vrednost ignorisana u ovom slučaju.

Za tipove zbirki koji podržavaju to,remove() metoda iteratora briše najposećenije elementre iz sadržine, dok čuva upotrebljive od strane iteratora. Dodavanje ili uklanjanje elemenata pozivanjem meotda sadržine (takođe od iste niti) čini iterator beskorisnim. Pokšaj da se sledeći element izbaci stvara izuzetak. Izuzetak se takođe odbacuje ako nema preostalih elemenata (hasNext() je vraćeno sa netačno).

Pored toga, za java.util.List postojijava.util.  sa sličnim API ali to dozvoljava prednje i zadnje ponavljanje, daje svoj trenutan indeks u listi i dozvoljava postavljanje elementa liste na njegovu poziciju.

J2SE 5.0 izdanje Jave predstavilo jeIterable interfejs kako bi podržalo poboljšanu for (forič) petlju za ponavljanje nad zbirkama i nizovima. Iterable definišeiterator() metodu koja vraćaIterator. Koristeći poboljšanu for petlju, prethodni primer može biti zapisan kao

for (MyType obj : list) {
    System.out.print(obj);
}

Neke sadržine koriste starije (još u 1.0) Enumeration klase. To omogućujehasMoreElements() i nextElement() metode, ali nema metode da promeni sadržinu.

Skala[uredi | uredi kod]

U Skali, iteratori imaju bogat izbor metoda sličnih zbirkama, i mogu se koristiti direktno u for petljama. Naravno, ova iteratora i zbirke nasleđuju čestu zajedničku osobinu- scala.collection.TraversableOnce. Međutim, zbog bogatog izbora metoda koje su dostupne u bilbioteci zbirke Skale, kao što je map, collect, filter, itd., često je neophodno da se ophodi sa iteratorima direktno kada se programira u Skali. 

Javini iteratori i kolekcije mogu biti automatski konvertovane u Skaline iteratore i kolekcije, odnosno, jednostavno dodavajući jedan red 

import scala.collection.JavaConversions._

u direktorijum. JavaKonverzija objekat omogućuje implicitnu konverziju. Implicitne konverzije su karakteristične za Skalu: metode koje, kada su vidljive u trenutnom vidokrugu, automatski ubacuju pozive sami sebi u relevantne ekspresije u pristojno mesto kako bih naterali da se preoveravaju kada oni to ne bi teli.

MATLAB[uredi | uredi kod]

MATLAB podržava i spoljne i unutrašnje implicitno ponavljanje koristeći "prirodne " redove ili cell redove. U slučaju spoljnog ponavljanja gde je teret nad korisnikom da unapredi prolaz i da zahteva sledeće elemente, može se definisati skup elemenata unutar niza strukture skladišta i preneti elemente koristeći se for-konstrukcijom petlje. Na primer,

% Definisati niz celih brojeva
myArray = [1,3,5,7,11,13];

for n = myArray
   % ... raditi nešto sa n
   disp(n)  % Echo ceo broj za Command Window
end

prolazi kroz niz celih brojeva koristećifor ključnu reč. U slučaju unutrašnjeg ponavljanja gde korisnik može snabdevati poreaciju iteratora da izvrši nad svim elementima zbirke, mnogi napravljeni operatori i MATLAB funkcije su preopterećeni izvršenjem nad svakim elementom niza i vraćaju implicitno odgovarajući izlazni niz. Osim toga, arrayfun i cellfun funkcije mogu biti iskorišćene za izradu slobodnih ili desinisanih od strane korisnika operacija nad "prirodnim" nizovima i cell nizova respektivno. Na primer,

function simpleFun
% Definisati niz celih brojeva
myArray = [1,3,5,7,11,13];

% Izvršiti proizvoljnu operaciju nad svakim elementom
myNewArray = arrayfun(@(a)myCustomFun(a), myArray);

% Echo rezultujući niz za Command Window 
myNewArray

function outScalar = myCustomFun(inScalar)
% Jednostavno pomnožen sa 2
outScalar = 2*inScalar;

definiše primernu funkciju simpleFun koja implicitno prihvata slobodnu podfunkciju myCustomFun svakog elementa niza koji koristi napravljenu funkcijuarrayfun.

Alternativno, može biti poželjno da se mehanizmi sadržine za skladištenje nizova učine abstraktnim od strane korisnika definisanjem proizvoljne objektno-orijentisane MATLAB implementacije Šablona Iteratora. Takva implementacija koja podržava spoljnu iteraciju je demonstrirana u MATLAB-u Centralnoj Razmeni Fajlova stavka Dizajn Šablona: Iterator (Ponašanje) . Ovo je napisano u novoj definiciji klase sintakse predstavljen sa MATLAB softverom verzije 7.6(R2008a) i ima realizaciju jedno-dimenzionalnog cell niza Abstraktne Liste Tipa Podataka(ADT) kao mehanizam za čuvanje heterogena ( tipa podataka) seta elemenata. To omogučuje funkcionalnost za eksplicitnu naprednu Listu prolaza sahasNext(), next() i reset() metoda za korišćenje u while-petlji.

PHP[uredi | uredi kod]

PHP-ova forič petlja je predstavljena u verziji 4.0 i kompatibilna je sa predmetima kao vrednosti u 4.0 Beta 4 Forič petlja.[13] Međutim, podrška za iteratore je dodata u PHP 5 kroz predstavljanje  internog[14] Prenosiog interfejs.[15] Dva glavna interfejsa za realizaciju u PHP skriptama koji omogućuju predmetima da budu ponavljani preko forič petlje su Iterator i AgregatIteratora. Ovo posledlje ne zahteva implementaciju klase kako bi se deklarisale sve tražene metode, umesto toga ono ubacuje metodu acesoara (getIterator) koja vraća instancu Prenosnog . Standardna PHP Biblioteka omogućuje nekoliko klasa da rade sa specijalnim iteratorima.[16] PHP takođe podržava Generatore još od 5.5.[17]

Najjednostavnija implementacija je umotavanjem niza, ovo može biti korisno za kucanje i sakrivanje informacija.

namespace Wikipedia\Iterator;

final class ArrayIterator extends \Iterator {

    private $array;

    public function __construct(array $array) {
        $this->array = $array;
    }

    public function rewind() {
        echo 'rewinding' , PHP_EOL;
        reset($this->array);
    }

    public function current() {
        $value = current($this->array);
        echo "current: {$value}" , PHP_EOL;
        return $value;
    }

    public function key() {
        $key = key($this->array);
        echo "key: {$key}" , PHP_EOL;
        return $key;
    }

    public function next() {
        $value = next($this->array);
        echo "next: {$value}" , PHP_EOL;
        return $value;
    }

    public function valid() {
        $valid = $this->current() !== false;
        echo 'valid: ' , ($valid ? 'true' : 'false') , PHP_EOL;
        return $valid;
    }
}

Sve metoda primera klase se koriste tokom izvršenja kompletne forič petlje (foreach ($iterator as $key => $current) {}). Iteratorove metode se izvršavaju po sledećem redosledu:

  1. $iterator->rewind() osigurava da unutrašnja struktura počne ispočetka.
  1. $iterator->valid() vraća tačno u ovom primeru.
  1. $iterator->current() vraćena vrednost je sačuvana u $value.
  1. $iterator->key() vraćena vrednost je sačuvana u $key.
  1. $iterator->next() napreduje na sledeći element u unutrašnjoj strukturi.
  1. $iterator->valid() vraća netačno i šetlja je prekinuta.

Sledeći primer ilustruje PHP klasu koja ubacuje Prenosni interfejs, koji bi mogao biti obmotan u IteratorIterator clasu da deluje na podatke pre nego što se vrati u forič petlju. Korišćenje zajedno sa MYSQLI_USE_RESULT konstantom dozvoljava PHP skriptama da ponavljaju rezultate setova sa bilionima redova sa svakim mali korišćenjem memorije. Ove karakteristike nisu isključivo za PHP ili za njegovu MySQL implementaciju klase (npr. PDONaredba klase ubacuje Prenosni interfejs takođe).

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli('host.example.com', 'username', 'password', 'database_name');

// \mysqli_result klasa koje je vraćena metodom poziva implemenata internog Taversable sučelja.

foreach ($mysqli->query('SELECT `a`, `b`, `c` FROM `table`', MYSQLI_USE_RESULT) as $row) {
    // Deluje na vraćeni red, koji je asocijativni niz.

}

Pajton[uredi | uredi kod]

Iteratoru u Pajtonu su fundamentalni deo jezika i u mnogim slučajevima prođu neviđeni pošto se implicitno koriste u for (forič) naredbama, u listama shvatanja i u ekspresijama generatora. Sve Pajtonove standardne zbirke tipova podržavaju ponavljanje, kao i mnogo klase koje su deo standardne biblioteke. Sledeći primer pokazuje tipično implicitno ponavljanje preko sekvence:

 for value in sequence:
     print(value)

Pajtonovi rečnici (forma asocijativnih nizova) moge takođe da budu direktno ponavljani, kada su ključevi rečnika vraćeni; ili metoda predmeta bude ponavljana gde se daje odgovarajući ključ, parovi vrednosti kao n-torka:

for key in dictionary:
    value = dictionary[key]
    print(key, value)
for key, value in dictionary.items():
    print(key, value)

Iteratori međutim se mogu koristiti i definisati eksplicitno. ZA svaku iterablu tipa sekvence ili klase, ugrađena funkcija iter() se koristi da napravi predmet iteratora. Predmet iteratora može biti ponavljan sai next() funkcijom koja koristi __next__() metodu iznutra, koja vraća sledeći element sadržine (prethodna naredba se odnosi na Pajton 3.x. U Pajton 2.x, next() metoda je ekvivivalentna). StopIteration izuzetak će se podići kada nema preostalih elemenata. Sledeći primer pokazuje ekvivalentno ponavljanje nad sekvencom koristeći eksplicitne iteratore:

it = iter(sequence)
while True:
    try:
        value = it.next() # u Pajtonu 2.x
        value = next(it) # u Pajtonu 3.x
    except StopIteration:
        break
    it = iter(it)
    print(value)

Bilo koja klasa definisana od korisnika može podržati standardno ponavljanje (bilo implicitno ili eksplicitno) definišući metodu __iter__() koja vraća predmet iteratora. Predmet iteratora onda traži da se definiše __next__() metoda koja vraća sledeći element i __iter__() metodu koja vraća sledeći predmet iteratora za korišćenje

Pajtonov generator ubacuje ovaj protokol ponavljanja.

Rubi[uredi | uredi kod]

Rubi ubacuje iteratore dosta drugačije; sva ponavljanja se dešavaju uz pomoć donošenja povratnog zatvaranja metoda sadržine- na ovaj način Rubi ne samo da ubacuje osnovno ponavljanje ali takođe nekoliko šablona ponavljanja kao funkcija mapovanja, filtera i smanjivanja. Rubi takođe podržava alternativnu sintaksu osnovnog metoda ponavljanja each, sldeća tri primera su ekvivalentna:

(0...42).each do |n|
  puts n
end

…i…

for n in 0...42
  puts n
end

ili kraće

42.times do |n|
  puts n
end

Rubu može ponavljati nad popravljenim listama koristeći Popisivače ili pozivanjem njihove #sledeće metoda ili radći forič petlju nad njima, kao što je gore .

Vidi još[uredi | uredi kod]

Reference[uredi | uredi kod]

  1. Gatcomb, Joshua.
  2. 2,0 2,1 2,2 Watt, Stephen M. "A Technique for Generic Iteration and Its Optimization" (PDF).
  3. Alex Allain.
  4. 4,0 4,1 "Difference between an external iterator and an internal iterator".
  5. Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004).
  6. Vecerina, Ivan (2006-02-01). "index vs iterator".
  7. 7,0 7,1 7,2 Kevin Waterson.
  8. larsmans (2011-03-06).
  9. Collier, Andrew.
  10. "concurrent_unordered_set Template Class" Arhivirano 2015-05-01 na Wayback Machine-u.
  11. Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004).
  12. "java.util: Interface Iterator<E>: Method Summary".
  13. "PHP 4 ChangeLog".
  14. Internal refers to the fact that the interface cannot be implemented in PHP scripts, only in the C (programming language) source.
  15. "The Traversable interface".
  16. "Iterators".
  17. "PHP 5 ChangeLog".

Spoljašnje veze[uredi | uredi kod]