Start · Sprachen · JavaScript · Referenz · Segments.prototype[Symbol.iterator]()

Segments.prototype[Symbol.iterator]()

Methode

Gibt einen Iterator zurück, der nacheinander Segment-Datenobjekte (<code>{ segment, index, input, isWordLike }</code>) eines mit <code>Intl.Segmenter</code> segmentierten Strings liefert.

seit JavaScript ES2022 (Intl.Segmenter) – Baseline seit 2024, alle Kategorie: method-property

Signatur

Segments.prototype[Symbol.iterator]()

Beschreibung

Die Methode [Symbol.iterator]() von Segments-Instanzen implementiert das iterierbare Protokoll. Ein Segments-Objekt entsteht durch Intl.Segmenter.prototype.segment(string). Durch den Iterator kann man es direkt mit for...of, dem Spread-Operator [...segments], Array.from() oder Destrukturierung verwenden.

Jeder Iterationsschritt liefert ein Segment-Datenobjekt mit diesen Eigenschaften:

  • segment – der Teilstring des Segments (Graphem, Wort oder Satz)
  • index – der Startindex des Segments im ursprünglichen String (in UTF-16-Codeeinheiten)
  • input – der vollständige segmentierte String
  • isWordLike – nur bei granularity: "word": true, wenn das Segment ein „Wort“ ist (Buchstaben, Zahlen), sonst false für Leerzeichen und Satzzeichen. Bei anderen Granularitäten ist es undefined.

Den Iterator braucht man immer dann, wenn man Text sprachabhängig korrekt zerlegen will, z. B. um sichtbare Zeichen einschließlich Emojis und Kombinationszeichen zu zählen, Wörter in Sprachen ohne Leerzeichen (Japanisch, Thai, Chinesisch) zu trennen oder Text in Sätze aufzuteilen. Die Segmentierung passiert dabei lazy: Die Segmente werden erst beim Weiterschalten des Iterators berechnet.

Rückgabewert

Typ
Iterator<{ segment: string, index: number, input: string, isWordLike?: boolean }>
Beschreibung
Ein neues Segment-Iterator-Objekt (erbt von Iterator.prototype), dessen next()-Methode nacheinander die Segment-Datenobjekte liefert.

Beispiele

Sichtbare Zeichen (Grapheme) korrekt zählen

const segmenter = new Intl.Segmenter('de', { granularity: 'grapheme' });
const text = 'Hallo 👋🏽 Welt 👨‍👩‍👧';

// Spread nutzt intern [Symbol.iterator]()
const graphemes = [...segmenter.segment(text)];

console.log(text.length);        // UTF-16-Codeeinheiten
console.log(graphemes.length);   // tatsächlich sichtbare Zeichen
22 14

Wörter mit for...of und isWordLike zählen

const segmenter = new Intl.Segmenter('de', { granularity: 'word' });
const text = 'Das ist ein Test, oder nicht?';

const words = [];
for (const { segment, isWordLike } of segmenter.segment(text)) {
  // Leerzeichen und Satzzeichen überspringen
  if (isWordLike) words.push(segment);
}

console.log(words);
console.log(`Wortanzahl: ${words.length}`);
[ 'Das', 'ist', 'ein', 'Test', 'oder', 'nicht' ] Wortanzahl: 6

Japanischen Text ohne Leerzeichen in Wörter zerlegen

const segmenter = new Intl.Segmenter('ja', { granularity: 'word' });
const text = '吾輩は猫である。';

const words = Array.from(segmenter.segment(text), (s) => s.segment);
console.log(words.join(' | '));
吾輩 | は | 猫 | で | ある | 。

Iterator manuell verwenden und Satzindizes ermitteln

const segmenter = new Intl.Segmenter('de', { granularity: 'sentence' });
const segments = segmenter.segment('Erster Satz. Zweiter Satz! Dritter?');

const it = segments[Symbol.iterator]();
let result = it.next();
while (!result.done) {
  const { segment, index } = result.value;
  console.log(index, JSON.stringify(segment));
  result = it.next();
}
0 "Erster Satz. " 13 "Zweiter Satz! " 27 "Dritter?"

// Wichtig · Fallstricke

  • Kompatibilität: Intl.Segmenter ist in Chrome/Edge 87+, Safari 14.1+, Node.js 16+ verfügbar, in Firefox aber erst ab Version 125 (April 2024). Für ältere Umgebungen braucht man eine Feature-Erkennung ('Segmenter' in Intl) oder ein Polyfill.
  • Die genaue Segmentierung, vor allem bei Wörtern, hängt von den ICU-Daten der jeweiligen Engine ab. Die Ergebnisse können sich zwischen Browsern und Versionen leicht unterscheiden. Verlasse dich in Tests also nicht auf exakte Wortgrenzen.
  • index zählt UTF-16-Codeeinheiten, nicht Grapheme. Es passt deshalb zu String.prototype.slice(), aber nicht zur Position in [...str].
  • Jeder Aufruf von [Symbol.iterator]() erzeugt einen neuen Iterator. Ein Segments-Objekt lässt sich also mehrfach durchlaufen, ein einzelner Iterator ist nach dem Durchlauf aber verbraucht.
  • isWordLike ist nur bei granularity: 'word' gesetzt, sonst undefined.
  • Performance: Bei sehr langen Texten ist for...of mit frühem break günstiger als [...segments], weil die Segmente lazy berechnet werden. Für gezielte Abfragen an einer Position gibt es Segments.prototype.containing(index).