Benutzer:Rolf b/JavaScript/Array
Ein Array ist eine Datenstruktur, die mehrere Werte unter einem gemeinsamen Namen speichert. Auf diese Werte kann mit einem ganzzahligen Index zugegriffen werden. Der Index bestimmt auch die Reihenfolge der Werte im Array. Die gespeicherten Werte werden auch als Arrayelemente bezeichnet.
Der Begriff „Array“ wird in der Literatur unterschiedlich übersetzt. Manche übersetzen ihn gar nicht, andere sprechen von einer Tabelle oder einem Feld. Beides kann irreführend sein, darum bleiben wir beim englischen Begriff. In anderen Programmiersprachen werden Arrays auch als Liste, Vektor oder Matrix genannt.
Grundsätzlich sind JavaScript-Arrays Objekte, allerdings mit - wie die Spezifikation es nennt - exotischem Verhalten. Die Exotik besteht darin, dass Array-Objekte ein spezielles Verhalten aufweisen, wenn man einen ganzzahligen Wert aus dem Bereich vorzeichenloser 32-bit Integers (0 - 4294967294) als Eigenschaftsname verwendet.
Kennzeichnend für Arrays in JavaScript sind die folgenden Merkmale:
- Die Werte in einem Array sind nicht auf einen bestimmten Typ festgelegt. Auch Arrays oder Objekte können als Wert in einem Array gespeichert werden
- Arrays sind eindimensional. Tabellen oder Datenwürfel können dadurch nachgebildet werden, dass man Arrays in Arrays speichert oder die Indizes in eine einzelne Zahl umrechnet.
- Ein Array hat eine
length
-Eigenschaft. JavaScript speichert dort automatisch den Wert des höchsten genutzten Index plus 1. Dielength
-Eigenschaft kann aber auch gesetzt werden, um ein Array zu kürzen oder leere Einträge anzufügen. - Wenn Sie als Index etwas anderes als einen 32-bit Integerwert verwenden, wirft JavaScript keinen Fehler. Statt dessen wird der Indexwert in eine Zeichenkette umgewandelt und wie eine Objekteigenschaft behandelt. Die Arraylänge wird davon nicht beeinflusst.
Inhaltsverzeichnis
Erstellung
Um ein Array zu erzeugen, gibt es zwei Möglichkeiten. Am einfachsten ist die Verwendung eines so genannten Arrayliterals. Unter „Literal“ versteht man einen konstanten, im Programmcode abgelegten Wert:
const farben = [ 'rot', 'orange', 'gelb', 'grün', 'blau' ];
console.log(farben);
Der Variablen farben
wird ein Array mit 5 Elementen zugewiesen. Diese haben die Indexwerte von 0 bis 4. 'rot' bekommt den Index 0, 'orange' den Index 1, 'blau' die 4.
Index | Wert |
---|---|
0 | rot |
1 | orange |
2 | gelb |
3 | grün |
4 | blau |
Die Alternative ist die Verwendung der Array-Konstruktorfunktion. Ihre Beschreibung und Beispiele finden Sie im Referenzartikel zu Arrays, aber ihr Gebrauch ist nur in Ausnahmefällen erforderlich. Erstellen Sie neue Arrays aus Literalen.
Arrayliterale als Fabrik
Wir haben vorhin gesagt, dass ein Literal ein im Programmcode abgelegter konstanter Wert sei. Das stimmt für Arrayliterale nicht ganz. Das Arrayliteral im Programm ist nicht das gleiche wie das Array, das daraus entsteht. Statt dessen müssen Sie sich ein Arrayliteral wie eine Arrayfabrik vorstellen. Diese Fabrik kann Konstanten verarbeiten, aber auch Variablen oder sogar Ausdrücke.
const y = 3;
for (let x=2; x<10; x+=3) {
const array = [ 4, x, 2*x-y, y ];
console.log(array);
}
Die Ausgabe ist
(4) [ 4, 2, 1, 3 ] (4) [ 4, 5, 7, 3 ] (4) [ 4, 8, 13, 3 ]
Wenn das Literal Variablen enthält, werden diejenigen Werte benutzt, die im Moment der Literalverwendung in den Variablen enthalten sind.
Zugriff auf Arrayelemente
Um ein einzelnes Element in einem Array anzusprechen, verwendet man den Indexoperator:
const farben = ['rot', 'orange', 'gelb', 'grün', 'blau'];
console.log('Die dritte Farbe ist', farben[2]);
Der Indexoperator besteht aus zwei eckigen Klammern. Er wird so angewendet, dass man die öffnende Klammer hinter die Variable mit dem Array darin setzt, dann den Index angibt und dahinter die schließende Klammer setzt. Wie bei allen Operatoren kann sowohl das Array wie auch der Index durch einen Ausdruck ermittelt werden, worauf hier noch nicht eingegangen werden soll.
Die Ausgabe des obigen Beispiels ist
Die dritte Farbe ist gelb
Frage: Wieso wurde für die dritte Farbe der Index 2 verwendet?
Antwort anzeigen
Arrayindizes beginnen bei 0. Erste Farbe: Index 0. Zweite Farbe: Index 1. Dritte Farbe: Index 2.
Verändern von Arrayelementen
Das Ergebnis eines Ausdrucks ist normalerweise ein fester Wert, aber ein Indexausdruck wie farben[2]
hat eine Besonderheit: er repräsentiert das Arrayelement mit Index 2 und akzeptiert deshalb auch eine Wertezuweisung.
const farben = ['rot', 'orange', 'gelb', 'grün', 'blau'];
farben[2] = 'gold';
console.log('Die dritte Farbe ist', farben[2]);
Die Zuweisung in der zweiten Beispielzeile verändert das in farben
gespeicherte Array. Die Ausgabe wird deshalb so aussehen:
Die dritte Farbe ist gold
farben
wurde als const
definiert. Wieso ist überhaupt eine Zuweisung an farben[2]
möglich?Antwort anzeigen
Man muss zwischen der Variable
farben
und dem darin befindlichen Array unterscheiden. Die Zuweisung farben = ['kotzgelb', 'hornhautumbra', 'popelgrün'];
const
-Deklaration der Variablen, in der es gespeichert ist, deshalb können seine Elemente weiterhin verändert werden. Einen Schutz vor Veränderung könnten Sie mit Hilfe von Object.freeze(farben) erreichen.Wir können nun das Versprechen vom Anfang einlösen und zeigen, wie man ein Array nachträglich erweitert. Weisen Sie einfach einer bisher unbenutzten Indexnummer einen Wert zu:
const farben = ['rot', 'orange', 'gelb', 'grün', 'blau' ];
farben[9] = 'pink';
console.log(farben);
Die Ausgabe ist etwas überraschend:
(10) ['rot', 'orange', 'gelb', 'grün', 'blau', leer × 4, 'pink']
Tatsächlich besteht eine Lücke zwischen den Elementen. Sie können sie nachträglich durch weitere Zuweisungen füllen, aber zunächst einmal sieht das Array nun so aus:
Index | Wert |
---|---|
0 | rot |
1 | orange |
2 | gelb |
3 | grün |
4 | blau |
9 | pink |
Und es stellt sich gleich eine weitere Frage: Was passiert, wenn ich auf farben[6]
zugreife? Dieses Element gibt es nicht. Bekommt man einen Blue Screen für einen Speicherzugriffsfehler?
Antwort anzeigen
Glücklicherweise nicht. Wie bei jedem Zugriff auf eine Objekteigenschaft, die nicht existiert, erhalten Sie den Wert undefined
.
Die Eigenschaft length
Eine weitere „exotische“ Eigenschaft von Arrays ist length
. Diese Eigenschaft wird von JavaScript automatisch jedem Array zugeordnet. Die grundsätzliche Idee ist, dass man mit length
abfragen kann, wieviele Elemente in einem Array gespeichert sind. Solange es keine leeren Einträge gibt, trifft das auch zu.
const farben = [ 'rot', 'orange', 'gelb', 'grün', 'blau' ];
console.log('Ich habe', farben.length, 'Farben');
farben[10] = 'pink';
console.log('Jetzt habe ich', farben.length, 'Farben');
Die Ausgabe dieses Scripts ist:
Ich habe 5 Farben Jetzt habe ich 10 Farben
Moment, zehn? Es wurde doch nur ein weiteres Arrayelement hinzugefügt. An dieser Stelle ist die Erklärung, dass farben.length
die Anzahl der Arrayelemente angibt, nicht mehr ganz richtig. Tatsächlich prüft JavaScript bei jeder Zuweisung an ein Arrayelement, ob der verwendete Index größer oder gleich dem bisherigen Wert für length
ist. Wenn ja, wird length
auf den nächst größeren Wert gesetzt.
Es ist einfach so, dass diese leeren Arrayelemente eine Form der Speicheroptimierung darstellen, man aber erreichen wollte, dass sich ein Array so verhält wie in klassischen Programmiersprachen, deren Arrays lückenlos sind. Deswegen bekommen Sie undefined
beim Zugriff auf ein nicht existierendes Arrayelement, und deshalb erhalten Sie mit dem Index farben.length - 1<
das Arrayelement mit dem höchsten genutzten Index.
Und deswegen ist der höchste mögliche Arrayindex auch 4294967294 (232</sub>-2) und nicht 4294967295. Sowohl Indizes wie auch length
sollen sich als vorzeichenloser 32-bit Integer darstellen lassen, und der Index 4294967295 würde length
zum Überlaufen bringen.
Kürzen und Erweitern eines Arrays
Eine interessante Eigenschaft von length
ist, dass diese Eigenschaft nicht nur gelesen, sondern auch verändert werden kann. Wenn Sie einen Wert zuweisen, werden alle Elemente, deren Index größer oder gleich diesem Wert sind, aus dem Array entfernt.
const farben = ['rot', 'orange', 'gelb', 'grün', 'blau'];
farben.length = 4;
console.log('Ich habe jetzt', farben.length, 'Farben');
console.log(farben);
Die Konsolenausgabe ist
Ich habe jetzt 4 Farben (4) ['rot', 'orange', 'gelb', 'grün']
Wenn Sie andererseits length
auf einen höheren Wert setzen, als es den verwendeten Indizes im Array entspricht, zeigt JavaScript Ihnen Leerwerte an.
{{Beispiel
const farben = ['rot', 'orange', 'gelb', 'grün', 'blau'];
// Zuerst kürzen, um den unwiederbringlichen Verlust zu zeigen
farben.length = 4;
farben.length = 14;
console.log('Ich habe jetzt', farben.length, 'Farben');
console.log(farben);
Die Konsolenausgabe ist nun
Ich habe jetzt 14 Farben (14) ['rot', 'orange', 'gelb', 'grün', leer × 10]
Wie gesagt: beim Kürzen eines Arrays sind die entfernten Werte weg. Nachträgliches Erweitern bringt sie nicht zurück.
Grundlegende Array-Operationen
Den Zugriff über den Index-Operator sowie die Abfrage und Änderung der Länge sind längst nicht alles, was man mit Arrays machen kann.
JavaScript-Arrays sind Objekte und besitzen damit Eigenschaften. Die beschriebene length
-Eigenschaft wird jedem Array direkt zugeordnet. Darüber hinaus verfügt jedes Array über etliche Methoden, die es von Array.prototype
vererbt bekommt. Eine ausführliche Beschreibung finden Sie über die Array-Referenzseite.
Verwendung als Stapel oder Schlange
Stapel (Stack) und Schlange (Queue) sind zwei grundlegende Verfahren, Daten zu organisieren. Die Links im vorigen Satz führen zu Erklärungen dieser Verfahren in der Wikipedia.
Für die Stapeloperationen push und pop bieten Arrays direkte Methoden an. Sie funktionieren so, dass push ein neues Element an das Array anfügt und pop das letzte Element des Arrays entfernt. Die Stapeloperation peek wird hingegen nicht direkt unterstützt, hierfür müssen Sie sich mit array[array.length-1]
behelfen. Weil das zuletzt (last) gespeicherte Element dasjenige ist, das zuerst (first) wieder entnommen werden kann, spricht man bei einem Stapel auch von einem LIFO-Speicher (last-in, first-out).
const stapel = [];
stapel.push(3);
stapel.push(7);
stapel.push(1);
while (stapel.length > 0) {
console.log('Stapelzustand:', stapel);
console.log(stapel.pop());
}
Die Ausgabe ist
Stapelzustand: ▸ (3) [3, 7, 1] 1 Stapelzustand: ▸ (2) [3, 7] 7 Stapelzustand: ▸ (1) [3] 3
Das Beispiel erzeugt eine Variable stapel
und initialisiert sie mit einem leeren Array, das als Stapelspeicher verwendet werden soll. Danach wird die push-Methode benutzt, um drei Werte auf den Stapel zu legen, und anschließend werden diese drei Werte in einer [[1]] wieder ausgelesen: Solange die Länge des Arrays größer als 0 ist, soll der oberste Stapelwert entnommen und ausgegeben werden. Sie sehen, dass die Ausgabe in umgekehrter Reihenfolge wie die push-Operationen erfolgt.
Die Standardoperationen für Warteschlangen nennen sich enqueue (neuen Wert an die Warteschlange anfügen) und dequeue (ältesten Wert entnehmen). Hier wird das zuerst eingespeicherte Objekt als erstes wieder entnommen, weshalb man auch von einem FIFO-Speicher spricht (first-in, first-out). Es gibt allerdings in JavaScript keine Methoden dieses Namens. Statt dessen müssen Sie sich entscheiden: Möchten Sie neue Elemente vorn im Array einfügen (an Position 0) und vom Ende her lesen? Oder lieber am Ende einfügen und von vorher her lesen? Davon hängt ab, welche Methoden Sie benutzen müssen. Zu empfehlen ist eigentlich, am Ende einzufügen und von vorn zu lesen, weil dann mit dem Zugriff auf Indexposition 0 die peek-Operation sehr einfach wird.
Die enqueue-Operation ist dann genau wie bei einem Stapel mit Hilfe der push()
-Methode durchführbar. Um das Element an Indexposition 0 aus dem Array zu entfernen und die übrigen Elemente um eine Indexposition nach unten zu verschieben, gibt es die Methode shift(). Beachten Sie, dass diese Methode teuer ist, weil der Array-Inhalt dafür auf jeden Fall umkopiert werden muss.
const queue = [];
queue.push(3);
queue.push(7);
queue.push(1);
while (queue.length > 0) {
console.log('Warteschlangeninhalt:', queue);
console.log(queue.shift());
}
Die Ausgabe ist
Warteschlangeninhalt: ▸ (3) [3, 7, 1] 3 Warteschlangeninhalt: ▸ (2) [7, 1] 7 Warteschlangeninhalt: ▸ (1) [1] 1
Wir haben damit Methoden zum Anfügen am Arrayende, Wegnehmen am Arrayende und Wegnehmen am Arrayanfang. Da fehlt noch etwas: Anfügen am Arrayanfang. Auch das gibt es: unshift(). Auch diese Methode ist teuer, weil zunächst alle Arrayelemente um eine Indexposition hochkopiert werden müssen, um Platz für die Einfügung bei Index 0 zu machen.
Durchlaufen eines Arrays
Klassisch durchläuft man ein Array mit einer for-Schleife:
const array = [5, 8, 1];
for (let i=0; i < array.length; i++) {
console.log('Der Wert an Position', i, 'ist', array[i]);
}
Arrays besitzen eine besondere Eigenschaft: sie sind iterierbar. Das bezieht sich auf ein neueres Feature von JavaScript, die Iterator-Schnittstelle, die es ermöglicht, ein iterierbares Objekt mit der for...of-Schleife zu durchlaufen oder den Spread-Operator darauf anzuwenden. Ein Iterator weiß nichts von Indexpositionen, kann aber die vorhandenen Werte der Reihe nach bereitstellen. Die for...of-Schleife nimmt sie entgegen. Falls die Positionen interessieren, muss man selbst mitzählen.
const array = [5, 8, 1];
let pos = 0;
for (let wert of array) {
console.log('Der Wert an Position', pos, 'ist', wert);
pos = pos + 1;
}
Der Spread-Operator ...
kann ein Array ebenfalls durchlaufen. Er wird verwendet, um die einzelnen Werte eines iterierbaren Objekts in ein Arrayliteral oder auf die Parameter einer Funktion zu verteilen. Unser Fabrikmodell für ein Arrayliteral wird damit um eine Wiederholungsmaschine erweitert:
const array1 = [ 1, 2, 3 ];
const array2 = [ 10, 11, ...array1];
console.log(array2);
Die Ausgabe ist
(5) [10, 11, 1, 2, 3]
Durch den Spread-Operator werden die Elemente von array1
in das Arrayliteral verteilt, aus dem </code>array2</code> gebildet wird. Es ist, als ob Sie [10, 11, array1[0], array1[1], array1[2]]
geschrieben hätten.
Die dritte gängige Methode, ein Array zu durchlaufen, ist die foreach-Methode. Bei ihr ist die eigentliche Schleife in der Methode versteckt, und den Schleifeninhalt stellen Sie in Form einer Funktion bereit, die pro Durchlauf einmal aufgerufen wird. Die Funktion bekommt den aktuellen Arraywert, seinen Index und - der Vollständigkeit halber - auch noch das ganze Array übergeben. Solche Funktionen nennt man Callbacks.
const array = [5, 8, 1];
array.forEach(function(wert, index, arr) {
console.log('Der Wert an Position', index, 'ist', wert);
});
Das Beispiel verwendet eine anonyme Funktion, häufig sind als forEach-Callback auch Pfeilfunktionen anzutreffen. Die Ausgabe ist
Der Wert an Position 0 ist 5 Der Wert an Position 1 ist 8 Der Wert an Position 2 ist 1
Das Array selbst haben wir in der für dieses Beispiel nicht benötigt, wir hätten den arr-Parameter deshalb auch weglassen können.
for...of oder forEach
Dies ist eine häufige Diskussion. Viele Programmierer sind Fans eines funktionalen Stils und verwenden forEach bei jeder sich bietenden Gelegenheit. Als Rechtfertigung kann man angeben, dass durch die Callback-Funktion die Daten des Schleifenrumpfs gekapselt sind. Das ist richtig, stammt aber aus der Zeit, wo Variablen mit var
deklariert wurden. Dadurch, dass die mit let und const definierten Variablen Blockscope haben, sind die Daten des Schleifeninhalts auch ohne eine Callback-Funktion gekapselt.
Arrayinhalte transformieren, filtern und prüfen
Es gibt etliche weitere Array-Methoden, die Callbacks erwarten und damit Array-Operationen durchführen können. Solche Operationen kann man mit Hilfe von Schleifen selbst programmieren, das ist aber eine lästige Standardlogik, die von fertigen Arraymethoden übernommen werden kann.
Beispiele für die genannten Funktionen finden Sie auf den verlinkten Referenzseiten.
Um den Inhalt eines Arrays zu transformieren, können Sie die Methode map verwenden. Damit erzeugen Sie ein neues Array, in dem auf jedes Element des zu transformierenden Arrays die Callback-Funktion angewendet wird und ihr Rückgabewert im neuen Array gespeichert wird.
Die Methode filter verwendet einen Callback, um Elemente auszuwählen. Nur diejenigen Elemente, für die die Callback-Funktion true zurückgibt, werden in ein neues Array kopiert.
Es gibt Fälle, wo man wissen möchte, ob eine bestimmte Bedingung für einige (also für mindestens eins) oder für alle Arrayelemente erfüllt ist. Wenn ich ein Array mit Namen habe - ist dann ein Name dabei, der mit "Q" beginnt? Oder sind alle Namen kürzer als 20 Zeichen? Um solche Fragen zu beantorten, können Sie some- und every-Methoden anwenden.
Mehrdimensionale Arrays
Oftmals sind Daten nicht nur einfache Vektoren, sondern Gebilde mit zwei oder noch mehr Dimensionen. Eine zweidimensionale Tabelle hat man beispielsweise, wenn man stündliche Temperaturwerte einer Wetterstation über mehrere Tage betrachtet. Die erste Dimension sind die Tage, die zweite Dimension die Stunden. Benötigt man nun noch die Daten mehrerer Wetterstationen, sind es schon drei Dimensionen.
Es gibt Programmiersprachen, die mehrdimensionale Arrays unterstützen. JavaScript gehört nicht dazu. Statt dessen können Sie Arrays als Werte in ein anderes Array eintragen und damit eine Art Arrayhierarchie erzeugen.
const station3 = [
[ 5, 5, 4, 4, 3, 2, 2, 3, 4, 7, 10, 11, 12, 12, 13, 12, 10, 8, 5, 3, 1, 0, -1, -1 ],
[ -2, -3, -5, -6, -7, -7, -8, -8, -6, -3, 0, 2, 3, 3, 4, 3, 3, 2, 1, 0, -1, -1, -2, -3 ],
];
console.log('Tag 2, 12 Uhr:', station3[1][12], 'Grad');
Den Zugriff station3[1][12]
müssen Sie von links nach rechts lesen. Hier finden zwei Arrayzugriffe statt: In station
befindet sich ein Array mit 2 Elementen, und mit station[1]
erhalten Sie das zweite davon. Auf dieses Array wird nun mit dem zweiten Indexoperator zugegriffen und das dreizehnte Element ermittelt - was dem 12 Uhr-Wert entspricht, wenn der erste Messwert von 0 Uhr ist.
Frage: Wenn Sie sich mental in der Sprache BASIC befinden und station3[1,0]
schreiben, erhalten Sie keinen Programmfehler, sondern das Array für den ersten Tag. Was tut JavaScript da?
Antwort anzeigenUm das zu beantworten, muss man den Aneinanderreihungsoperator kennen: das Komma. Hiermit kann man mehrere Ausdrücke nacheinander auswerten lassen und erhält als Ergebnis den Wert des letzten Ausdrucks. Der Indexoperator erhält den Ausdruck (1, 0)
als Index, und dessen Wert ist 0.
Statt das Array als Literal zu erzeugen, können Sie es auch Stück für Stück in einer Schleife aufbauen. Nehmen wir an, es gäbe eine Funktion liesTemperatur
, der man die Nummer der Station, den Tag und die Stunde übergibt und die daraufhin den entsprechenden Messwert aus dem Archiv holt. Das folgende Beispiel verwendet diese fiktive Funktion, um damit ein dreidimensionales Arraykonstrukt zu erzeugen:
const messwerte = [];
for (let station=0; station < 4; station++) {
// Für jede Station als erstes ein leeres Tage-Array erzeugen
messwerte[station] = [];
for (let tag=0; tag < 31; tag++) {
// Für jeden Tag als erstes ein leeres Stunden-Array erzeugen
messwerte[station][tag] = [];
for (let stunde=0; stunde < 24; stunde++) {
// Messwerte für jede Stunde holen
messwerte[station][tag][stunde] = liesTemperatur(station, tag, stunde);
}
}
}
console.log('Messwerte von Tag 5, 17 Uhr:');
for (let station = 0; station < 4; station++) {
console.log(' Station', station, ': ', messwerte[station][4][17], 'Grad');
}
Dieser Code ist schon schwieriger zu lesen. Hier werden drei Schleifen ineinander geschachtelt, um in der innersten Schleife für jede Stunde jedes Tages jeder Station den entsprechenden Messwert zu speichern.
Nachdem der Datenwürfel aufgebaut ist, wird in einer einfachen Schleife für eine bestimmte Stunde der Messwert für jede Station ausgegeben.
Assoziative Arrays
Der Begriff „assoziatives Array“ ist verbreitet, führt aber in die Irre. Mit dem, was JavaScript unter einem Array versteht, hat ein assoziatives Array nichts zu tun.
Gemeint ist hier die Möglichkeit, in einer Datenstruktur Werte über einen Namen zuordnen zu können. Man nennt ein solches Gebilde aber eher Dictionary, Map oder Key-Value-Collection. In PHP ist es etwas anders, dort hat der Array-Datentyp tatsächlich die Möglichkeit, Werte über einen Namen zuordnen zu können.
Der Einsatzzweck von assoziativen Arrays liegt darin, Werte unter Schlüsselnamen zu speichern, die sich erst während der Laufzeit des Programms ergeben. Sind sie beim Programmieren bereits bekannt, verwendet man gewöhnliche Objekte.
Aber stellen Sie sich vor, sie möchten in einem Text ermitteln, welches Wort wie oft vorkommt. Sie wissen beim Programmieren nicht, welche Wörter das sind, und jetzt brauchen Sie ein assoziatives Array. Oder eine Map. Für das folgende Beispiel lassen wir die Frage einmal außer acht, wie man einen Text in Wörter zerlegt. Das ist sicherlich eine interessante Aufgabe, aber nicht hier. Nehmen wir einfach an, diese Aufgabe hätte jemand anderes gelöst und stellt uns die Wörter nun in einem Array zur Verfügung. Wir müssen nur noch zählen. Früher hat man dafür ein leeres Objekt verwendet und für den Zugriff auf seine Eigenschaften die Index-Notation verwendet. Wie das geht, beschreiben wir im OOP-Tutorial unter [Eigenschaften]. Das geeignetere Werkzeug ist aber ein Map-Objekt.
// Testdaten
const wörter = [
'fischers', 'fritze', 'fischt', 'frische', 'fische',
'frische', 'fische', 'fischt', 'fischers', 'fritz' ];
const wortzähler = new Map();
for (let wort of wörter) {
if (wortzähler.has(wort)) {
wortzähler.set(wort, wortzähler.get(wort) + 1);
}
else {
wortzähler.set(wort, 1);
}
}
for (let wort of wortzähler.keys()) {
console.log(wort, 'kommt', wortzähler.get(wort), 'mal vor');
}
fischers kommt 2 mal vor fritze kommt 1 mal vor fischt kommt 2 mal vor frische kommt 2 mal vor fische kommt 2 mal vor fritz kommt 1 mal vor
Das Beispiel verwendet die for...of-Schleife zum Durchlaufen der Wörtertabelle. Dieser Schleifentyp ist am einfachsten, wenn man nur den Inhalt eines Arrays braucht und nicht die Indexpositionen.
Als nächstes begegnet uns ein technisches Problem. Wenn ein Wort noch nicht im Wortzähler drin ist, liefert uns wortzähler[wort]
das Ergebnis undefined
, und mit undefined
kann man nicht rechnen. Deshalb muss unterschieden werden, ob ein Wort schon vorhanden ist oder nicht, und dafür verwenden wir die Methode has
, mit der man prüfen kann, ob eine Map bereits einen bestimmten Schlüssel enthält. Ist es schon da, wird sein Wert mit wortzähler.get(wort) gelesen, um 1 erhöht und mit wortzähler.set(wort, ...) wieder geschrieben. Fehlt das Wort noch, wird es durch den set-Aufruf neu angelegt und sein Wert auf 1 gesetzt.
Nun bleibt die Frage, wie wir an die gezählten Wörter herankommen. Hier hilft uns die keys-Methode weiter, die jede Map anbietet. Sie liefert zwar kein Array, aber dafür einen sogenannten Iterator, auf den sich for...of ebenfalls anwenden lässt und damit alle in der Map gespeicherten Schlüssel durchläuft. In der Schleife werden die Zählerstände dann ausgelesen und ausgegeben.
Siehe auch
Weblinks
- ECMAScript: Array-objects
- MDN: Array