Читать книгу JavaScript – Das Handbuch für die Praxis - David Flanagan - Страница 16

Beispiel 1-1: Berechnung von Häufigkeitshistogrammen mit JavaScript

Оглавление

/**

* Dieses Node-Programm liest Text aus der Standardeingabe, berechnet für

* jedes Zeichen in diesem Text die Häufigkeit seines Vorkommens und zeigt

* ein Histogramm der am häufigsten verwendeten Zeichen. Zur Ausführung ist

* Node 12 oder höher erforderlich.

*

* In einer Unix-artigen Umgebung können Sie das Programm wie folgt aufrufen:

* node charfreq.js < corpus.txt

*/

// Diese Klasse erweitert Map so, dass die get()-Methode statt null den angegebenen

// Wert zurückgibt, falls der Schlüssel key nicht in der Map vorkommt.

class DefaultMap extends Map {

constructor(defaultValue) {

super(); // Ruft den Konstruktor der Superklasse auf.

this.defaultValue = defaultValue; // Standardwert merken.

}

get(key) {

if (this.has(key)) { // Wenn der Schlüssel bereits in der Map

// vorkommt,

return super.get(key); // wird dessen Wert aus der Superklasse

// zurückgegeben.

}

else {

return this.defaultValue; // Gibt ansonsten den Standardwert zurück.

}

}

}

// Diese Klasse berechnet und zeigt Buchstabenhäufigkeitshistogramme.

class Histogram {

constructor() {

this.letterCounts = new DefaultMap(0); // Zuordnung von Buchstaben

// zu Zählwerten.

this.totalLetters = 0; // Wie viele Buchstaben insgesamt?

}

// Diese Funktion aktualisiert das Histogramm mit den Zeichen des Texts.

add(text) {

// Entfernt Leerzeichen aus dem Text und konvertiert in Großbuchstaben.

text = text.replace(/\s/g, "").toUpperCase();

// Schleife über die Zeichen des Texts.

for(let character of text) {

let count = this.letterCounts.get(character); // Alten Zählwert auslesen.

this.letterCounts.set(character, count+1); // Inkrementieren.

this.totalLetters++;

}

}

// Konvertiert das Histogramm in eine Zeichenfolge, die eine ASCII-Grafik anzeigt.

toString() {

// Konvertiert die Map in ein Array von Schlüssel/Wert-Arrays.

let entries = […this.letterCounts];

// Sortiert das Array zuerst nach Anzahl und dann alphabetisch.

entries.sort((a,b) => { // Eine Funktion zur Festlegung der

// Sortierreihenfolge.

if (a[1] === b[1]) { // Wenn die Zählwerte identisch ist.

return a[0] < b[0] ? -1 : 1; // Alphabetisch sortieren.

} else { // Wenn die Zählwerte abweichen.

return b[1] - a[1]; // Sortierung nach der höchsten Anzahl.

}

});

// Rechnet die Ergebnisse in Prozentzahlen um.

for(let entry of entries) {

entry[1] = entry[1] / this.totalLetters*100;

}

// Alle Einträge unter 1 % fallen lassen.

entries = entries.filter(entry => entry[1] >= 1);

// Konvertiert jeden Eintrag in eine Textzeile.

let lines = entries.map(

([l,n]) => `${l}: ${"#".repeat(Math.round(n))} ${n.toFixed(2)}%`

);

// Und gibt die verketteten Zeilen, getrennt durch Zeilenumbruchzeichen,

// zurück.

return lines.join("\n");

}

}

// Diese asynchrone (ein Promise zurückgebende) Funktion erzeugt ein Histogrammobjekt,

// liest Textblöcke asynchron aus der Standardeingabe und fügt diese Blöcke dem

// Histogramm hinzu. Wenn das Ende des Streams erreicht wird, gibt es das Histogramm

// zurück.

async function histogramFromStdin() {

process.stdin.setEncoding("utf-8"); // Unicode-Strings lesen, nicht Bytes.

let histogram = new Histogram();

for await (let chunk of process.stdin) {

histogram.add(chunk);

}

return histogram;

}

// Die folgende letzte Codezeile ist der Hauptteil des Programms.

// Darin wird aus der Standardeingabe ein Histogrammobjekt erstellt und ausgegeben.

histogramFromStdin().then(histogram => { console.log(histogram.toString()); });

JavaScript  –  Das Handbuch für die Praxis

Подняться наверх