You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

Data-drevne løkker er løkker som er drevet av data i en samling, typisk fordi man ønsker å gjøre noe med hvert data-element.

Merk at Java har to typer løkker, generelle for-løkker og det som kalles for-each-løkker, fordi den går gjennom hvert element i en samling. Begge varianter bruker for-nøkkelordet, og for-each-varianten er såkalt syntaktisk sukker (eng: syntactic sugar), siden den kun er en kortform for noe en kan få til den generelle-for-løkka.

For-each-løkker

I en del løkker er poenget å behandle et sett med data, så betingelsen koker ned til om det er mere data igjen. Istedenfor å gjøre det manuelt med en teller som øker og sjekkes mot antall data-elementer, så har en del språk en egen kontrollstruktur som gjerne kalles for-each, for å gå gjennom alle data-elementer i en samling. En slik for-each-løkke holder både styr på om det er flere data-elementer igjen og sørger for å sette en løkke-variabel til neste element i rekka:

Gjør noe for hvert element i en liste

initialiser liste med navnsett navn til neste navn i lista:skriv ut 'Hei ' + navnsannflere navn igjenusann
Python
names = ['Chris', 'Pat', 'Sam']
for name in names:
    print 'Hei ' + name
Java
String[] names = {"Chris", "Pat", "Sam"};
for (String name : names) {
	System.out.println("Hei " + name);
}

Denne løkkevarianten er som regel avhengig av at dataene ligger i en datastruktur som har støtte for det som kalles en iterator. En iterator er et objekt som hjelper til med iterasjon, typisk ved at den nettopp holder rede på hvor langt en er kommet i gjennomløpningen av elementer. Så hvis en ny type datastruktur ønsker å støtte for-each løkker, så må en implementere en passende iterator.

I Java er Iterator et standard grensesnitt med to metoder:

  • boolean hasNext(): Denne metoden brukes for å spørre om det er flere elementer, uten at en faktisk går fremover.
  • Object next(): Denne metoden returnerer neste element i rekka, og sørger for å gå ett hakk fremover, slik at den neste gang returnerer neste element etter der igjen. next()-metoden er kun garantert å returnere noe dersom hasNext() har returnert true, så en bør alltid sjekke det først.

To løkker med iterator er vist under:

Iterator it = ...
while (it.hasNext()) {
	Object element = it.next();
	// gjør noe med element her...
}

Generell iterator-løkke.

Collection<String> strings = Arrays.asList("en", "to", "tre");
Iterator<String> it = strings.iterator();
while (it.hasNext()) {
	String element = it.next();
	// gjør noe med element her...
}

Iterator støtter generics, og da vil next returnere et element med en mer spesifikk type enn Object, f.eks. String som her.

Python sin tilsvarende iterator-klasse har kun én metode og bruker unntak når en når slutten på rekka av elementer:

  • next(): returnerer neste elementer, tar ett steg forover og utløser StopIteration-unntaket når slutten er nådd.

Generell for-løkke

Hvis en datastruktur ikke har en passende iterator, men f.eks. støtter oppslag med en posisjon eller indeks, så kan en falle tilbake på den generelle for-løkka. Dette brukes f.eks. for å løpe gjennom alle tegnene i en String, slik som vist under til venstre. Du må også bruke den generelle varianten, hvis du skal gå gjennom elementene i en annen rekkefølge enn standard-iteratoren for en datastruktur, f.eks. baklengs eller annenhvert element. Under i midten og til høyre ser du løkker for disse to tilfellene for en Java-liste.

 

String string = "123";
for (int i = 0; i < string.length(); i++) {
	char c = string.charAt(i);
	// gjør noe med c her...
}

Løkke for å gå gjennom tegnene i en String

List<String> strings = Arrays.asList("en", "to", "tre");
for (int i = strings.size() - 1; i >= 0; i--) {
	String element = strings.get(i);
	// gjør noe med element her...
}

Løkke for å gå gjennom elementene i en List baklengs.

List<String> strings = Arrays.asList("en", "to", "tre");
for (int i = 0; i < strings.size(); i = i + 2) {
	String element = strings.get(i);
	// gjør noe med element her...
}

Løkke for å gå gjennom annenhvert element i en List.

Bruk av for-each på egne datastrukturer

I Java brukes Iterable-grensesnittet som brobygger til for-each-syntaksen.

 

  • No labels