Abschnitt 4 · Lektion 5
Synthese: das Einmaleins
Der Abschluss dieses Abschnitts bringt zusammen, was einzeln schon dastand: zwei Schleifen ineinander, eine Bedingung darin, und ein Text, der Stück für Stück wächst.
Das Ergebnis ist eine Tabelle, und Tabellen haben eine Eigenschaft, die man beim Programmieren gern unterschätzt: Man sieht sofort, ob sie stimmt.
Erst hinschreiben, dann erzeugen
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // So soll es aussehen. Von Hand hingeschrieben, bevor eine
// einzige Schleife existiert.
console.log("Zeile 1: 1 2 3");
console.log("Zeile 2: 2 4 6");
console.log("Zeile 3: 3 6 9");
console.log("---");
// Und jetzt dieselbe Ausgabe, erzeugt statt getippt.
for (let zeile = 1; zeile <= 3; zeile++) {
let text = "Zeile " + zeile + ":";
for (let spalte = 1; spalte <= 3; spalte++) {
text += String(zeile * spalte).padStart(5);
}
console.log(text);
} Der Handgriff, der bei jeder erzeugten Ausgabe hilft: Schreib zuerst von Hand hin, wie das Ergebnis aussehen soll. Drei Zeilen reichen.
Damit hast du ein Ziel, das du anschauen kannst, statt einer Vorstellung im Kopf. Du siehst, wo Leerzeichen hingehören, wie breit die Spalten sein müssen und was am Zeilenanfang steht. Und wenn deine Schleife läuft, kannst du beides untereinanderlegen und vergleichen.
Ohne diesen Schritt baust du die Schleife und die Formatierung gleichzeitig, und wenn das Ergebnis krumm aussieht, weißt du nicht, welches von beidem schuld ist.
Sammeln statt einzeln ausgeben
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // So nicht: jede Zahl bekommt ihre eigene Zeile.
console.log("Einzeln ausgegeben:");
for (let zeile = 1; zeile <= 2; zeile++) {
for (let spalte = 1; spalte <= 3; spalte++) {
console.log(zeile * spalte);
}
}
console.log("---");
// So schon: die Zeile wird gesammelt und einmal ausgegeben.
console.log("Gesammelt:");
for (let zeile = 1; zeile <= 2; zeile++) {
let text = "";
for (let spalte = 1; spalte <= 3; spalte++) {
text += zeile * spalte + " ";
}
console.log(text);
} Die erste Fassung im Beispiel gibt jede Zahl einzeln aus. Das Ergebnis ist eine lange Spalte, und von einer Tabelle ist nichts zu sehen.
Der Grund ist, dass console.log immer eine ganze Zeile schreibt. Es gibt keine Möglichkeit, etwas an die vorige Zeile anzuhängen.
Also sammelst du die Zeile in einem Text und gibst sie einmal aus, wenn sie fertig ist. Der Text wird vor der inneren Schleife angelegt und nach ihr ausgegeben. Das ist genau das Muster aus Lektion 4.4, und hier siehst du, wozu es gut ist.
Auf einer echten Seite ist es später dasselbe: Du baust erst den ganzen Abschnitt Markup zusammen und hängst ihn dann in einem Stück ein, statt zehnmal einzeln. Das ist Abschnitt 11.
Ausrichten mit padStart
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Ohne Ausrichtung rutschen die Spalten, sobald eine Zahl länger wird.
console.log("Ohne padStart:");
for (let zeile = 8; zeile <= 10; zeile++) {
let text = "";
for (let spalte = 8; spalte <= 10; spalte++) {
text += zeile * spalte + " ";
}
console.log(text);
}
console.log("---");
// padStart füllt links mit Leerzeichen auf, bis die Breite stimmt.
console.log("Mit padStart:");
for (let zeile = 8; zeile <= 10; zeile++) {
let text = "";
for (let spalte = 8; spalte <= 10; spalte++) {
text += String(zeile * spalte).padStart(5);
}
console.log(text);
} Sobald die Zahlen verschieden lang sind, rutschen die Spalten. Im Einmaleins kommen ein-, zwei- und dreistellige Zahlen vor, damit ist das garantiert.
padStart(breite) füllt einen Text links mit Leerzeichen auf, bis er die gewünschte Breite hat. Ist er schon länger, passiert nichts. Es gibt auch padEnd, das rechts auffüllt.
Zwei Dinge dazu:
Es ist eine Textmethode, keine Zahlenmethode. Deshalb steht String(...) darum. Bei einer Zahl direkt bekommst du einen TypeError.
Links auffüllen ist bei Zahlen das Richtige. Zahlen liest man von rechts, die Einerstelle soll also untereinanderstehen. Bei Wörtern ist es umgekehrt, da nimmt man padEnd.
Warum das hier überhaupt geht, ohne CSS: Die Console benutzt eine Schrift, in der jedes Zeichen gleich breit ist. Bei einer normalen Schrift auf einer Webseite funktioniert das nicht, dort richtet man mit CSS aus.
Eine Stelle auslassen
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Wo Zeile und Spalte gleich sind, kommen vier Leerzeichen statt
// der Zahl. Die Lücke behält ihre Breite, das Raster bleibt stehen.
for (let zeile = 1; zeile <= 4; zeile++) {
let text = "";
for (let spalte = 1; spalte <= 4; spalte++) {
if (spalte === zeile) {
text += " ";
continue;
}
text += String(zeile * spalte).padStart(4);
}
console.log(text);
} Die letzte Zutat ist eine Bedingung mitten in der inneren Schleife.
Wo Zeile und Spalte gleich sind, liegt die Diagonale, also 1 mal 1, 2 mal 2 und so weiter. Die soll ausgelassen werden.
Wichtig dabei: Die Lücke behält ihre Breite. Statt der Zahl kommen vier Leerzeichen, nicht gar nichts. Ließe man die Stelle einfach weg, würde der Rest der Zeile nach links rutschen und das Raster wäre hin. Genau daran erkennt man beim Anschauen sofort, ob es richtig gemacht wurde.
Das continue ist hier übrigens Geschmackssache; ein else täte dasselbe. Es passt nur gut zum Muster aus Lektion 4.3: Sonderfall oben abfangen, danach steht der Normalfall ohne zusätzliche Einrückung da.
Zum Mitnehmen
Schreib zuerst hin, wie die Ausgabe aussehen soll. Danach ist die Schleife nur noch die Frage, wie du dorthin kommst.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.