3.11.2020

Arrays und Schleifen

Grundwissen Programmieren Teil 3

Arrays und Schleifen

Dies ist Teil 3 unserer Blogpost-Serie “Grundwissen Programmieren”.

Einer der Gründe, warum wir Menschen die Computer erfunden haben, ist, dass sie uns nervige, eintönige, sich ständig wiederholende Tätigkeiten abnehmen, ohne sich darüber zu beschweren. Sie können so enorm große Mengen an Daten verarbeiten, bei denen wir, wenn wir sie von Hand machen müssten, wahrscheinlich vor Langeweile und Frust grau werden würden.

Stell dir folgende Situation vor: du bist Angestellter bei einer sehr erfolgreichen Software-Firma. Die Software, die deine Firma verkauft, hat über 10.000 zahlende Kunden, die monatlich ihre Subscription Fee bezahlen. Nun hat sich der Geschäftsführer aus wirtschaftlichen Gründen dafür entschieden, dass die Firma zu einem neuen Bankkonto wechselt. Deine Aufgabe ist nun, jeden einzelnen Kunden per Email über diese Änderung zu informieren. Oje…!

Stell dir vor du müsstest das nun per Hand machen: durch eine Liste von 10.000 Kunden gehen und jeden einzelnen per Email anzuschreiben. Du würdest wahrscheinlich sofort kündigen. 😅 Zum Glück gibt es für genau diese Zwecke Programmiersprachen, die genau diese Art von eintönigen, langwierigen Aufgaben automatisieren können. In Wiederholungen (oder Loops, wie man sie auf Englisch nennt) liegt die große Stärke von Programmiersprachen.

In diesem Artikel werde ich dir nicht zeigen, wie du Emails automatisch an 10.000 Leute schicken kannst (du Strolch! 👆). Dafür zeige ich dir, wie du in JavaScript Schleifen baust und in Listen gespeicherte Daten (Arrays) damit durchgehen kannst. Ich zeige dir, wie man Arrays erstellt, auf die Daten darin zugreift und wie man darüber iteriert. Dies ist eins der wichtigsten Konzepte in der Programmierung, das du auf jeden Fall meistern musst, wenn du Programmierer werden willst.

Alle Code-Beispiele in diesem Blog Post kannst du hier nachsehen. Um das Meiste aus diesem Artikel herauszuholen, empfehle ich dir, dass du dir dein eigenes Repl auf replit.com erstellst und alle Schritte selbstständig nachprogrammierst.

Immer und immer wieder das Gleiche tun: Schleifen

Bart Simpson

Nehmen wir an, du müsstest den Satz “I will use loops for repetitions” 20 mal hintereinander auf der Konsole ausgeben. Wie würdest du das angehen? Du könntest natürlich 20 mal hintereinander diese Zeile schreiben:

console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")
console.log("I will use loops for repetitions")

Mit Copy-und-Paste wäre das ja auch machbar. Aber du hast richtig vermutet: es gibt einen einfacheren Weg, das zu tun.

JavaScript hat einen sogenannten for-Loop, der genau für diese Art von Wiederholung gemacht ist. Man benutzt ihn, um damit denselben Code mehrmals hintereinander auszuführen.

In unserem Beispiel würde der for-Loop so aussehen:

for (var i = 0; i < 20; i++) {
  console.log("I will use loops for repetitions")
}

Viel besser, oder? Kurz und bündig. 😊
Du musst die Zeile mit dem console.log nur einmal schreiben, und der Loop nimmt dir die Wiederholung ab.

Lass uns den for-Loop einmal auseinander nehmen, um alle seine Teile besser zu verstehen.

for (...) {
  ...
}

Das for signalisiert dem Programm: dies ist ein Loop – wiederhole diesen Code … mal. Alles, was zwischen den geschweiften Klammern {} steht, wird wiederholt.

var i = 0;

Hier erstellen wir uns eine Variable namens i. Das ist eine Hilfsvariable.
Es ist Konvention, dass man diese Variable i nennt: i wie index.
Mit jeder Wiederholung der Schleife wird sich i erhöhen.

Beachte: i fängt immer bei 0 an, nicht bei 1. In der Programmierung fängt man immer bei 0 an zu zählen. Wir werden darauf später nochmal genauer eingehen.

i < 20;

Dieses Statement sagt: wiederhole die Schleife so lange wie i kleiner als 20 ist.
Wir werden gleich sehen, was das bedeutet, wenn wir uns das nächste Statement ansehen:

i++

Das bedeutet: erhöhe (increment) i um 1. Es ist das gleiche, als würde man schreiben i = i + 1.

📝 Für dein Cheat Sheet:
i++ ist das Gleiche wie i = i + 1

Wenn wir nochmal auf den ganzen for-Loop schauen, verstehen wir nun, was passiert.

for (var i = 0; i < 20; i++) { ...

Das bedeutet also:

  • Zuerst wird eine Variable i erstellt, die einen initialen Wert von 0 hat.
  • Dann soll die Schleife so lange wiederholt werden, bis i < 20.
  • Und für jede Iteration soll i um 1 erhöht werden: i++.

Im ersten Durchlauf ist i 0, im zweiten Durchlauf 1, im dritten 2 und so weiter, so lange bis i 20 ist und die Bedingung i < 20 nicht mehr erfüllt ist.

Um das nochmal etwas greifbarer zu machen, ändern wir das console.log ein Bisschen, und geben das i mit aus:

for (var i = 0; i < 20; i++) {
  console.log("I will use loops for repetitions " + i)
}

Die Ausgabe hiervon ist:

I will use loops for repetitions 0
I will use loops for repetitions 1
I will use loops for repetitions 2
I will use loops for repetitions 3
I will use loops for repetitions 4
I will use loops for repetitions 5
I will use loops for repetitions 6
I will use loops for repetitions 7
I will use loops for repetitions 8
I will use loops for repetitions 9
I will use loops for repetitions 10
I will use loops for repetitions 11
I will use loops for repetitions 12
I will use loops for repetitions 13
I will use loops for repetitions 14
I will use loops for repetitions 15
I will use loops for repetitions 16
I will use loops for repetitions 17
I will use loops for repetitions 18
I will use loops for repetitions 19

Hieran kann man schön sehen, dass i für jede Wiederholung, oder jede Iteration, wie es in der Programmierung genannt wird, erhöht wird, und dass es genau vor dem Punkt aufhört, an dem i 20 wird.

💡 In der Programmierung nennt man eine Wiederholung in einer Schleife eine Iteration.

Nimm dir ruhig ein wenig Zeit, um mit den Zahlen in deinem Programm herum zu spielen und beobachte, wie sich die Ausgabe verändert.

👩‍💻 Als Übungsaufgabe versuche mal alle Zahlen von 1 bis 100 auszugeben. (Obacht, hier ist ein kleiner Trick dabei!). Die Lösung kannst du dir hier anschauen.

Schleifen sind nicht nur auf Zahlen beschränkt. Meistens hat man anderweitige Daten, wie z.B. Listen von Strings oder ähnlichem.

Schauen wir uns dazu mal ein anderes Beispiel an: wir haben eine Liste von Namen und wollen die auf der Konsole ausgeben. Dafür brauchen wir ein Array.

Daten in Form von Listen: Arrays

In unserem vorherigen Blog Post hatten wir uns die verschiedenen Datentypen von JavaScript angeschaut. Zusätzlich zu Integer, String, Boolean usw. gibt es in JavaScript noch einen anderen Datentypen, mit dem man Daten in Listen speichern kann: das Array.

Ein Array ist im Prinzip eine Liste von Werten. Wenn man sich die Variable wie eine Box vorstellt, wo ein Wert drin ist, kann man sich ein Array wie ein ganzes Regal mit Fächern vorstellen, von denen jedes einen Wert enthält.

Array

Das hier ist ein String-Array. Alle Werte in den einzelnen Fächern sind Strings.

In JavaScript würdest du dieses Array so erstellen:

var greetings = [ "Hi", "Hey", "Hola", "Moin", "Hello" ];

Nehmen wir ein anderes Beispiel. Wir wollen eine Liste an Namen speichern. Das könnten wir so machen:

var names = [ "Teresa", "Eva", "Jonas", "Helder", "Clemens" ];

Das erstellt ein Array mit 5 Elementen: den 5 Strings “Teresa”, “Eva”, “Jonas”, “Helder” und “Clemens”. Dieses Array wird in der Variable names gespeichert – das ist jetzt der Name des Arrays, den wir benutzen können, um auf die Werte zuzugreifen.

Um auf einen bestimmten Namen aus dem Array zuzugreifen, benutzen wir den Namen des Arrays, die eckigen Klammern [] und den Index des Elements:

console.log(names[2])

Was ist der Index? Der Index ist die Position des Elements im Array.
Probier einmal aus, so auf das Array zuzugreifen. Was ist der Output? (Lösung: “Jonas”). Versuche auch ruhig einmal, was passiert, wenn du andere Zahlen einsetzt. Verstehst du, wie es funktioniert?

☝️ Achtung: Indizes fangen bei 0 an!

Eine Sache die du immer im Kopf behalten solltest: die Indizes von Arrays fangen immer bei 0 an. Das heißt, das erste Element hat den Index 0, das Zweite den Index 1, das Dritte den Index 2 und so weiter.

Indices

Das ist einfach so in der Welt der Programmierung. 🤷‍♀️ Man nennt das auf Englisch zero-based numbering, fallst du es googlen möchtest. Für Nicht-Programmierer ist das so merkwürdig, dass darüber gern Witze oder Memes gemacht werden.

Three programmers walk into a bar

Zurück zu unserem Array! Wie können wir alle Namen im Array ausgeben? Dazu müssen wir jeden Index einmal benutzen, etwa so:

console.log("Name 1:", names[0]);
console.log("Name 2:", names[1]);
console.log("Name 3:", names[2]);
console.log("Name 4:", names[3]);
console.log("Name 5:", names[4]);

Das sollte uns diese Ausgabe geben:

Name 1: Teresa
Name 2: Eva
Name 3: Jonas
Name 4: Helder
Name 5: Clemens

Hier kannst du ganz schön sehen, dass wir für das erste Element den Index 0 benutzen, für das zweite den Index 1 und so weiter. Ich glaube inzwischen hast du das Prinzip schon verstanden. 😉

Was passiert aber, wenn wir versuchen, auf das Array mit einem Index zuzugreifen, an dem es kein Element gibt? Versuchen wir das einmal mit, ähm…, 19!

console.log(names[19]);

Das gibt uns den folgenden Output:

undefined

Kein Wunder, stimmt’s? Das Array hat nur 5 Elemente, und der letzte Index davon ist 4. Also ist das Element am Index 19 (das 20. Element) nicht vorhanden, also undefined.

Um das zu üben und etwas klarer zu machen, erstellen wir nun ein neues Array mit Integers. Darin sollen die folgenden Werte stehen: 15, 3, 28, 2, 6, 17, 3, 29, 8, 9, 0, 10, 31, 5, 4.

var numbers = [15, 3, 28, 2, 6, 17, 3, 29, 8, 9, 0, 10, 31, 5, 4];

💡 Arrays können jede Art von Datentyp beinhalten.
(Sie können auch einen Mix von Datentypen beinhalten, aber damit beschäftigen wir uns in diesem Artikel erstmal nicht.)

Und jetzt wollen wir alle Werte des Arrays ausgeben.
Wir wissen ja, wie wir auf die einzelnen Elemente zugreifen: mit dem Namen des Arrays, den eckigen Klammern [] und dem Index. Also los!

console.log("Number 1:", numbers[0]);
console.log("Number 2:", numbers[1]);
console.log("Number 3:", numbers[2]);
console.log("Number 4:", numbers[3]);
console.log("Number 5:", numbers[4]);
console.log("Number 6:", numbers[5]);
console.log("Number 7:", numbers[6]);
console.log("Number 8:", numbers[7]);
console.log("Number 9:", numbers[8]);
console.log("Number 10:", numbers[9]);
console.log("Number 11:", numbers[10]);
console.log("Number 12:", numbers[11]);
console.log("Number 13:", numbers[12]);
console.log("Number 14:", numbers[13]);
console.log("Number 15:", numbers[14]);

Das sollte uns den folgenden Output geben:

Number 1: 15
Number 2: 3
Number 3: 28
Number 4: 2
Number 5: 6
Number 6: 17
Number 7: 3
Number 8: 29
Number 9: 8
Number 10: 9
Number 11: 0
Number 12: 10
Number 13: 31
Number 14: 5
Number 15: 4

Alles klar, ich benutze den Index numbers[index] um auf die einzelnen Zahlen in dem Array zuzugreifen, und bekomme die Zahl.

Aber jetzt haben wir eine mühsame Wiederholung: wir schreiben 15 Zeilen Code, die alle sehr ähnlich sind. Und du vermutest richtig: wir können Schleifen dafür verwenden, das Ganze zu vereinfachen!

Durch Arrays iterieren

Wie du oben schon gesehen hast, for-Loops sehen so aus:

for (var i = 0; i < 20; i++) {
  // do something
}

Hier wird die Schleife 20 mal wiederholt. Wir benutzen die Variable i, um von 0 bis 19 zu gehen (wir wiederholen die Schleife so lange wie die Bedingung i < 20 erfüllt ist), und erhöhen i in jedem Durchlauf um 1 (i++).

Das trifft sich gut – wir können i jetzt nämlich dafür benutzen, um auf unser Array zuzugreifen: numbers[i].
Probieren wir es aus.

for (var i = 0; i < 20; i++) {
  console.log(numbers[i]);
}

Ok, was passiert hier also genau?
Wir haben einen for-Loop, von dem wir die Variable i als index benutzen.

In der ersten Iteration ist i 0. Also wird das console.log mit dem Wert 0 so aufgerufen: console.log(numbers[0]);. Und numbers[0] gibt uns 15.

In der nächsten Iteration ist i 1. Also ist das wie wenn wir numbers[1] benutzen würden. Und das gibt 3 aus – der Wert an Position 1 (der zweite Wert) des Arrays.

In der nächsten Iteration ist i 2, und es ist als würden wir numbers[2] verwenden, was uns 28 gibt, weil das die Zahl am Index 2 im Array ist.

Und so geht es immer weiter, bis die Schleife aufhört nachdem i 19 war.
Die Schleife sollte dir folgenden Output geben:

15
3
28
2
6
17
3
29
8
9
0
10
31
5
4
undefined
undefined
undefined
undefined
undefined

Moment, fünf mal undefined? Was ist denn hier passiert? 🧐

Natürlich! Die Schleife soll so lange wiederholt werden solange i < 20 ist. Deswegen ruft sie auch numbers[15] auf, numbers[16] und so weiter, bis einschließlich numbers[19]. Und weil unser Array nur 15 Elemente hat (der letzte Index ist 14), geben diese letzten Durchläufe undefined aus.

Zum Glück gibt es eine Möglichkeit, wie wir solche Zugriffe auf nicht existierende Array-Elemente vermeiden können.

In JavaScript kann man sich die Länge des Array geben lassen:

numbers.length

Wenn du das mit console.log() ausgibst, wird es dir 15 ausgeben. Genau, weil wir 15 Elemente im Array haben. Im Gegensatz zum Index fängt dieser Wert bei 1 an zu zählen - so wie du es gewöhnt bist. 😉

Graf von Zahl zählt

💡 Du kannst dir die Länge des Array geben lassen indem du den Array-Namen benutzt, dann den Punkt, und dann length. Im Falle unseres Arrays names wäre das names.length.

Wie hilft uns jetzt dieses numbers.length bei unserem Loop?
Wir können es anstelle der 20 einsetzen:

for (var i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

Das gibt uns aus:

15
3
28
2
6
17
3
29
8
9
0
10
31
5
4

Es hört genau an der richtigen Stelle auf, weil numbers.length das Limit ist, an dem wir aufhören wollen. Auf diese Weise bekommen wir keine unnötigen undefined Werte mehr. 🎉

Das ist die gängige Praxis beim iterieren durch Arrays. Wenn du dir beim Lernen Notizen machst - das ist etwas, was da hinein gehört.

Diese Art durch Arrays zu iterieren hat auch noch einen anderen Vorteil: wir können dem Array weitere Elemente hinzufügen, und es wird immer noch genauso funktionieren.
Probier das hier mal aus:

numbers.push(25);

Das wird den Integer-Wert 25 zum numbers Array hinzufügen, und zwar ans Ende.

Elemente hinzufügen macht man mit dem Array-Namen, einem Punkt, dann push, die Klammern () und in die Klammern das Element, was du hinzufügen willst. Also allgemein gesprochen: arrayname.push(element).

Unser neues Element ist jetzt am Index 15: console.log(numbers[15]) gibt uns nun 25 anstelle von undefined. Und wenn wir jetzt durch unser Array iterieren wollen, können wir das genauso machen wie vorher, ohne jegliche Änderung:

for (var i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

Das sollte uns diesen Output geben:

15
3
28
2
6
17
3
29
8
9
0
10
31
5
4
25

Cool! Das hinzugefügte Element erscheint! 😁

Das Gleiche, nur anders: while-Loops

Es gibt noch etwas, was wir euch nicht vorenthalten wollen: es gibt eine zweite Art von Schleifen, den while-Loop:

var counter = 0;
while (counter < 12) {
  counter++;
  console.log(counter);
}

While-Loops sind eine Art minimalisierte Version des for-Loops. Sie wiederholen alles in den geschweiften Klammern {} solange die Kondition in den runden Klammern erfüllt ist, in unserem Beispiel solange counter < 12.

Beim While-Loop muss der Programmier selbst dafür sorgen, die Variable anzulegen (counter) und sie zu inkrementieren (counter++, du erinnerst dich: das ist dasselbe wie counter = counter + 1).

While-Schleifen benutzt man normalerweise für etwas andere Anwendungsfälle. In der Praxis werden sie deutlich seltener eingesetzt als for-Schleifen. Du kommst in 99% der Fälle mit einer for-Schleife aus. Aber jetzt hast du den while-Loop zumindest einmal gesehen, und verstehst, was er tut, wenn du einen siehst.

Wenn du mutig genug bist, kannst du einmal zur Übung unsere for-Schleife von oben, die durch das numbers Array iteriert, in eine while-Schleife umschreiben. Schaffst du das?

 


 

Cool, du hast es bis ans Ende des Artikels geschafft! Jetzt weißt du wie man Arrays und Schleifen benutzt. Das ist ein großer und super wichtiger Schritt auf deinem Weg zum Programmieren Lernen.

Und denk immer daran: Übung macht den Meister. Loops zu verstehen kann zu Anfang recht schwierig sein. Aber jedes mal wenn du eine Schleife und/oder ein Array benutzt, wird es einfacher. Bis es eines Tages so selbstverständlich geworden ist, dass du gar nicht mehr darüber nachdenken brauchst.

Um dich auf den Weg in diese Richtung zu bringen, haben wir noch eine Übung für dich: Erstelle ein Array mit Integers, nämlich das Alter von 10 Freunden oder Familienmitgliedern. Iteriere durch dieses Array und gebe jedes Alter mit console.log() aus - aber füge einen Emoji hinten an, und zwar einen 😀 wenn die Zahl gerade ist, und einen 🤨 wenn die Zahl ungerade ist.

Tipp: Du kannst herausfinden ob eine Zahl gerade oder ungerade ist (d.h. ob sie durch 2 teilbar ist), indem du den Modulo-Operator % verwendest.

Du kannst die Lösung hier nachschauen.

Danke für’s Lesen! Wenn dir dieser Artikel geholfen hat, teile es mit deinen Freunden. Wenn du irgendwo nicht weiterkommst, schreib mir eine Email. Ich helfe immer gern. 😊

Bilder von Unsplash, Bart’s Chalkboard, Reddit and Flickr.
Zurück zur Übersicht