So wählen Sie die Pluralform für Bereiche wie 1-3 Elemente
Verwenden Sie JavaScript, um die korrekte Pluralform bei der Anzeige von Zahlenbereichen auszuwählen
Einführung
Bereiche kommunizieren, dass ein Wert zwischen zwei Endpunkten liegt. Benutzeroberflächen zeigen Bereiche in Kontexten wie Suchergebnissen an, die „10-15 Treffer gefunden" anzeigen, Bestandssystemen, die „1-3 Elemente verfügbar" anzeigen, oder Filtern, die „2-5 Optionen auswählen" anzeigen. Diese Bereiche kombinieren zwei Zahlen mit beschreibendem Text, der grammatikalisch mit dem Bereich übereinstimmen muss.
Wenn Sie eine einzelne Anzahl anzeigen, wählen Sie zwischen Singular- und Pluralformen: „1 Element" versus „2 Elemente". Sprachen haben Regeln, die bestimmen, welche Form basierend auf der Anzahl gilt. Diese Regeln variieren je nach Sprache. Englisch verwendet Singular für eins und Plural für alle anderen Anzahlen. Polnisch verwendet unterschiedliche Formen für 1, 2-4 und 5 oder mehr. Arabisch hat sechs verschiedene Formen basierend auf der Anzahl.
Bereiche stellen eine andere Herausforderung dar. Die Pluralform hängt sowohl vom Start- als auch vom Endwert ab, nicht nur von einer einzelnen Zahl. Im Englischen verwendet „1-2 items" Plural, obwohl der Bereich bei 1 beginnt. Verschiedene Sprachen haben unterschiedliche Regeln zur Bestimmung, welche Pluralform auf einen Bereich zutrifft. Die selectRange()-Methode auf Intl.PluralRules behandelt diese sprachspezifischen Regeln automatisch.
Warum Bereiche unterschiedliche Pluralisierungsregeln benötigen
Die Verwendung der select()-Methode auf eine einzelne Zahl aus einem Bereich funktioniert nicht korrekt für alle Sprachen. Sie könnten denken, den Endwert des Bereichs zu verwenden, aber dies erzeugt in vielen Sprachen falsche Ergebnisse.
Betrachten Sie Englisch mit dem Bereich 0-1. Die Verwendung von select() auf den Endwert gibt „one" zurück, was nahelegt, dass Sie „0-1 item" anzeigen sollten. Dies ist grammatikalisch falsch. Die korrekte Form ist „0-1 items" mit dem Plural.
const rules = new Intl.PluralRules("en-US");
console.log(rules.select(1));
// Output: "one"
// But "0-1 item" is incorrect
// Correct: "0-1 items"
Verschiedene Sprachen haben explizite Regeln für Bereiche, die nicht mit ihren Regeln für einzelne Zahlen übereinstimmen. Im Slowenischen verwendet der Bereich 102-201 die "few"-Form, während einzelne Zahlen in diesem Bereich unterschiedliche Formen verwenden.
const slRules = new Intl.PluralRules("sl");
console.log(slRules.select(102));
// Output: "few"
console.log(slRules.select(201));
// Output: "few"
console.log(slRules.selectRange(102, 201));
// Output: "few"
Einige Sprachen verwenden den Startwert zur Bestimmung der Form, andere den Endwert und wieder andere beide Werte zusammen. Die selectRange()-Methode kapselt diese sprachspezifischen Regeln, sodass Sie diese nicht manuell implementieren müssen.
Eine PluralRules-Instanz für Bereiche erstellen
Erstellen Sie eine Intl.PluralRules-Instanz auf die gleiche Weise wie für einzelne Zahlen. Die Instanz stellt sowohl select() für einzelne Zahlen als auch selectRange() für Bereiche bereit.
const rules = new Intl.PluralRules("en-US");
Sie können beim Erstellen der Instanz Optionen angeben. Diese Optionen gelten sowohl für einzelne Zahlen als auch für Bereiche.
const rules = new Intl.PluralRules("en-US", {
type: "cardinal"
});
Die type-Option ist standardmäßig auf "cardinal" gesetzt, was das Zählen von Objekten behandelt. Sie können auch "ordinal" für Positionszahlen verwenden, obwohl ordinale Bereiche in Benutzeroberflächen weniger verbreitet sind.
Verwenden Sie dieselbe Instanz für mehrere Aufrufe wieder. Das Erstellen einer neuen Instanz für jede Pluralisierung ist verschwenderisch. Speichern Sie die Instanz in einer Variable oder cachen Sie diese nach Locale.
selectRange verwenden, um die Pluralkategorie für Bereiche zu bestimmen
Die selectRange()-Methode nimmt zwei Zahlen entgegen, die den Anfang und das Ende eines Bereichs darstellen. Sie gibt einen String zurück, der angibt, welche Pluralkategorie zutrifft: "zero", "one", "two", "few", "many" oder "other".
const rules = new Intl.PluralRules("en-US");
console.log(rules.selectRange(0, 1));
// Output: "other"
console.log(rules.selectRange(1, 2));
// Output: "other"
console.log(rules.selectRange(5, 10));
// Output: "other"
Im Englischen verwenden Bereiche fast immer die "other"-Kategorie, die der Pluralform entspricht. Dies entspricht der Art und Weise, wie englische Muttersprachler Bereiche natürlich mit Pluralnomen ausdrücken.
Sprachen mit mehr Pluralformen geben basierend auf ihren spezifischen Regeln unterschiedliche Kategorien zurück.
const arRules = new Intl.PluralRules("ar-EG");
console.log(arRules.selectRange(0, 0));
// Output: "zero"
console.log(arRules.selectRange(1, 1));
// Output: "one"
console.log(arRules.selectRange(2, 2));
// Output: "two"
console.log(arRules.selectRange(3, 10));
// Output: "few"
Der Rückgabewert ist immer einer der sechs standardmäßigen Pluralkategorienamen. Ihr Code ordnet diese Kategorien dem entsprechenden lokalisierten Text zu.
Bereichskategorien auf lokalisierte Zeichenketten abbilden
Speichern Sie die Textformen für jede Pluralkategorie in einer Datenstruktur. Verwenden Sie die von selectRange() zurückgegebene Kategorie, um den entsprechenden Text nachzuschlagen.
const rules = new Intl.PluralRules("en-US");
const forms = new Map([
["one", "item"],
["other", "items"]
]);
function formatRange(start, end) {
const category = rules.selectRange(start, end);
const form = forms.get(category);
return `${start}-${end} ${form}`;
}
console.log(formatRange(1, 3));
// Output: "1-3 items"
console.log(formatRange(0, 1));
// Output: "0-1 items"
console.log(formatRange(5, 10));
// Output: "5-10 items"
Dieses Muster trennt die Pluralisierungslogik vom lokalisierten Text. Die Intl.PluralRules-Instanz verarbeitet die Sprachregeln. Die Map enthält die Übersetzungen. Die Funktion kombiniert sie.
Fügen Sie für Sprachen mit mehr Pluralkategorien Einträge für jede Kategorie hinzu, die die Sprache verwendet.
const arRules = new Intl.PluralRules("ar-EG");
const arForms = new Map([
["zero", "عناصر"],
["one", "عنصر"],
["two", "عنصران"],
["few", "عناصر"],
["many", "عنصرًا"],
["other", "عنصر"]
]);
function formatRange(start, end) {
const category = arRules.selectRange(start, end);
const form = arForms.get(category);
return `${start}-${end} ${form}`;
}
console.log(formatRange(0, 0));
// Output: "0-0 عناصر"
console.log(formatRange(1, 1));
// Output: "1-1 عنصر"
Stellen Sie immer Text für jede Kategorie bereit, die die Sprache verwendet. Überprüfen Sie die Unicode CLDR-Pluralregeln oder testen Sie mit der API über verschiedene Bereiche hinweg, um zu ermitteln, welche Kategorien benötigt werden.
Wie verschiedene Locales Bereichspluralisation handhaben
Jede Sprache hat ihre eigenen Regeln zur Bestimmung der Pluralform von Bereichen. Diese Regeln spiegeln wider, wie Muttersprachler Bereiche natürlich ausdrücken.
const enRules = new Intl.PluralRules("en-US");
console.log(enRules.selectRange(1, 3));
// Output: "other"
const slRules = new Intl.PluralRules("sl");
console.log(slRules.selectRange(102, 201));
// Output: "few"
const ptRules = new Intl.PluralRules("pt");
console.log(ptRules.selectRange(102, 102));
// Output: "other"
const ruRules = new Intl.PluralRules("ru");
console.log(ruRules.selectRange(1, 2));
// Output: "few"
Englisch verwendet durchgängig "other" für Bereiche, wodurch Bereiche immer plural sind. Slowenisch wendet komplexere Regeln basierend auf den spezifischen Zahlen im Bereich an. Portugiesisch verwendet "other" für die meisten Bereiche. Russisch verwendet "few" für bestimmte Bereiche.
Diese Unterschiede zeigen, warum das Hardcodieren von Plurallogik für internationale Anwendungen scheitert. Die API kapselt das Wissen darüber, wie jede Sprache Bereiche handhabt.
Mit Intl.NumberFormat für vollständige Formatierung kombinieren
Echte Anwendungen müssen sowohl die Zahlen als auch den Text formatieren. Verwenden Sie Intl.NumberFormat, um die Bereichsendpunkte gemäß den Locale-Konventionen zu formatieren, und verwenden Sie dann selectRange(), um die korrekte Pluralform auszuwählen.
const locale = "en-US";
const numberFormat = new Intl.NumberFormat(locale);
const pluralRules = new Intl.PluralRules(locale);
const forms = new Map([
["one", "item"],
["other", "items"]
]);
function formatRange(start, end) {
const startFormatted = numberFormat.format(start);
const endFormatted = numberFormat.format(end);
const category = pluralRules.selectRange(start, end);
const form = forms.get(category);
return `${startFormatted}-${endFormatted} ${form}`;
}
console.log(formatRange(1, 3));
// Output: "1-3 items"
console.log(formatRange(1000, 5000));
// Output: "1,000-5,000 items"
Der Zahlenformatierer fügt Tausendertrennzeichen hinzu. Die Pluralregeln wählen die korrekte Form aus. Die Funktion kombiniert beides, um eine korrekt formatierte Ausgabe zu erzeugen.
Verschiedene Locales verwenden unterschiedliche Konventionen zur Zahlenformatierung.
const locale = "de-DE";
const numberFormat = new Intl.NumberFormat(locale);
const pluralRules = new Intl.PluralRules(locale);
const forms = new Map([
["one", "Artikel"],
["other", "Artikel"]
]);
function formatRange(start, end) {
const startFormatted = numberFormat.format(start);
const endFormatted = numberFormat.format(end);
const category = pluralRules.selectRange(start, end);
const form = forms.get(category);
return `${startFormatted}-${endFormatted} ${form}`;
}
console.log(formatRange(1000, 5000));
// Output: "1.000-5.000 Artikel"
Deutsch verwendet Punkte als Tausendertrennzeichen anstelle von Kommas. Der Zahlenformatierer behandelt dies automatisch. Die Pluralregeln bestimmen, welche Form von "Artikel" verwendet werden soll.
Vergleich von selectRange mit select für Einzelwerte
Die Methode select() verarbeitet einzelne Anzahlen, während selectRange() Bereiche verarbeitet. Verwenden Sie select() bei der Anzeige einer einzelnen Menge und selectRange() bei der Anzeige eines Bereichs zwischen zwei Werten.
const rules = new Intl.PluralRules("en-US");
// Single count
console.log(rules.select(1));
// Output: "one"
console.log(rules.select(2));
// Output: "other"
// Range
console.log(rules.selectRange(1, 2));
// Output: "other"
console.log(rules.selectRange(0, 1));
// Output: "other"
Bei einzelnen Anzahlen hängen die Regeln nur von dieser einen Zahl ab. Bei Bereichen berücksichtigen die Regeln beide Endpunkte. Im Englischen verwendet ein Bereich, der bei 1 beginnt, dennoch die Pluralform, obwohl die einzelne Anzahl 1 die Singularform verwendet.
Einige Sprachen zeigen dramatischere Unterschiede zwischen Regeln für einzelne Anzahlen und Bereichsregeln.
const slRules = new Intl.PluralRules("sl");
// Single counts in Slovenian
console.log(slRules.select(1));
// Output: "one"
console.log(slRules.select(2));
// Output: "two"
console.log(slRules.select(5));
// Output: "few"
// Range in Slovenian
console.log(slRules.selectRange(102, 201));
// Output: "few"
Slowenisch verwendet "one", "two" und "few" für verschiedene einzelne Anzahlen basierend auf komplexen Regeln. Für Bereiche wendet es eine andere Logik an, die beide Zahlen zusammen berücksichtigt.
Behandlung von Bereichen, bei denen Start und Ende gleich sind
Wenn die Start- und Endwerte identisch sind, zeigen Sie einen Bereich ohne Breite an. Einige Anwendungen verwenden dies, um einen exakten Wert in einem Kontext darzustellen, in dem Bereiche erwartet werden.
const rules = new Intl.PluralRules("en-US");
console.log(rules.selectRange(5, 5));
// Output: "other"
console.log(rules.selectRange(1, 1));
// Output: "one"
Wenn beide Werte 1 entsprechen, gibt Englisch "one" zurück, was darauf hindeutet, dass Sie die Singularform verwenden sollten. Wenn beide Werte eine andere Zahl sind, gibt Englisch "other" zurück, was die Pluralform nahelegt.
Dieses Verhalten ist sinnvoll, wenn Sie den Bereich als „1-1 Element" oder einfach „1 Element" anzeigen. Für andere Werte als 1 zeigen Sie „5-5 Elemente" oder „5 Elemente" an.
In der Praxis möchten Sie möglicherweise erkennen, wann Start gleich Ende ist, und einen einzelnen Wert anstelle eines Bereichs anzeigen.
const rules = new Intl.PluralRules("en-US");
const forms = new Map([
["one", "item"],
["other", "items"]
]);
function formatRange(start, end) {
if (start === end) {
const category = rules.select(start);
const form = forms.get(category);
return `${start} ${form}`;
}
const category = rules.selectRange(start, end);
const form = forms.get(category);
return `${start}-${end} ${form}`;
}
console.log(formatRange(1, 1));
// Output: "1 item"
console.log(formatRange(5, 5));
// Output: "5 items"
console.log(formatRange(1, 3));
// Output: "1-3 items"
Dieser Ansatz verwendet select() für gleiche Werte und selectRange() für tatsächliche Bereiche. Die Ausgabe liest sich natürlicher, da die Anzeige von „1-1" oder „5-5" vermieden wird.
Randfälle mit selectRange behandeln
Die Methode selectRange() validiert ihre Eingaben. Wenn einer der Parameter undefined, null ist oder nicht in eine gültige Zahl konvertiert werden kann, löst die Methode einen Fehler aus.
const rules = new Intl.PluralRules("en-US");
try {
console.log(rules.selectRange(1, undefined));
} catch (error) {
console.log(error.name);
// Output: "TypeError"
}
try {
console.log(rules.selectRange(NaN, 5));
} catch (error) {
console.log(error.name);
// Output: "RangeError"
}
Validieren Sie Ihre Eingaben, bevor Sie sie an selectRange() übergeben. Dies ist besonders wichtig bei der Arbeit mit Benutzereingaben oder Daten aus externen Quellen.
function formatRange(start, end) {
if (typeof start !== "number" || typeof end !== "number") {
throw new Error("Start and end must be numbers");
}
if (isNaN(start) || isNaN(end)) {
throw new Error("Start and end must be valid numbers");
}
const category = rules.selectRange(start, end);
const form = forms.get(category);
return `${start}-${end} ${form}`;
}
Die Methode akzeptiert Zahlen, BigInt-Werte oder Strings, die als Zahlen geparst werden können.
const rules = new Intl.PluralRules("en-US");
console.log(rules.selectRange(1, 5));
// Output: "other"
console.log(rules.selectRange(1n, 5n));
// Output: "other"
console.log(rules.selectRange("1", "5"));
// Output: "other"
String-Eingaben werden als Zahlen geparst. Dies ermöglicht Flexibilität beim Aufruf der Methode, aber Sie sollten nach Möglichkeit tatsächliche Zahlentypen übergeben, um die Klarheit zu gewährleisten.
Dezimalbereiche behandeln
Die Methode selectRange() funktioniert mit Dezimalzahlen. Dies ist nützlich bei der Anzeige von Bereichen gebrochener Mengen wie Messungen oder Statistiken.
const rules = new Intl.PluralRules("en-US");
console.log(rules.selectRange(1.5, 2.5));
// Output: "other"
console.log(rules.selectRange(0.5, 1.0));
// Output: "other"
console.log(rules.selectRange(1.0, 1.5));
// Output: "other"
Englisch behandelt alle diese Dezimalbereiche als Plural. Andere Sprachen können unterschiedliche Regeln für Dezimalbereiche haben.
Kombinieren Sie beim Formatieren von Dezimalbereichen selectRange() mit Intl.NumberFormat, das für die entsprechende Dezimalpräzision konfiguriert ist.
const locale = "en-US";
const numberFormat = new Intl.NumberFormat(locale, {
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
const pluralRules = new Intl.PluralRules(locale);
const forms = new Map([
["one", "kilometer"],
["other", "kilometers"]
]);
function formatRange(start, end) {
const startFormatted = numberFormat.format(start);
const endFormatted = numberFormat.format(end);
const category = pluralRules.selectRange(start, end);
const form = forms.get(category);
return `${startFormatted}-${endFormatted} ${form}`;
}
console.log(formatRange(1.5, 2.5));
// Output: "1.5-2.5 kilometers"
console.log(formatRange(0.5, 1.0));
// Output: "0.5-1.0 kilometers"
Der Zahlenformatierer stellt eine konsistente Dezimaldarstellung sicher. Die Pluralregeln bestimmen die korrekte Form basierend auf den Dezimalwerten.
Browser-Unterstützung und Kompatibilität
Die selectRange()-Methode ist im Vergleich zum Rest der Intl-API relativ neu. Sie wurde 2023 als Teil der Intl.NumberFormat v3-Spezifikation verfügbar.
Die Browser-Unterstützung umfasst Chrome 106 und höher, Firefox 116 und höher, Safari 15.4 und höher sowie Edge 106 und höher. Die Methode ist im Internet Explorer oder älteren Browser-Versionen nicht verfügbar.
Für Anwendungen, die auf moderne Browser abzielen, können Sie selectRange() ohne Polyfill verwenden. Wenn Sie ältere Browser unterstützen müssen, prüfen Sie die Existenz der Methode, bevor Sie sie verwenden.
const rules = new Intl.PluralRules("en-US");
if (typeof rules.selectRange === "function") {
// Use selectRange for range pluralization
console.log(rules.selectRange(1, 3));
} else {
// Fall back to select with the end value
console.log(rules.select(3));
}
Dieser Fallback-Ansatz verwendet select() auf den Endwert, wenn selectRange() nicht verfügbar ist. Dies ist linguistisch nicht perfekt für alle Sprachen, bietet jedoch eine angemessene Annäherung für ältere Browser.
Polyfills sind über Pakete wie @formatjs/intl-pluralrules verfügbar, wenn Sie umfassende Unterstützung für ältere Umgebungen benötigen.
Wann selectRange anstelle von select verwendet werden sollte
Verwenden Sie selectRange(), wenn Ihre Benutzeroberfläche explizit einen Bereich mit sowohl Start- als auch Endwerten anzeigt, die für den Benutzer sichtbar sind. Dies umfasst Kontexte wie Suchergebnisse, die "10-15 Treffer gefunden" anzeigen, Inventar, das "1-3 Artikel auf Lager" anzeigt, oder Filter, die "2-5 Optionen auswählen" anzeigen.
Verwenden Sie select(), wenn Sie eine einzelne Anzahl anzeigen, auch wenn diese Anzahl einen ungefähren oder zusammengefassten Wert darstellt. Zum Beispiel verwendet "Etwa 10 Ergebnisse" select(10), da Sie eine einzelne Zahl anzeigen, keinen Bereich.
Wenn Ihr Bereich mit Intl.NumberFormat.formatRange() für die Zahlen angezeigt wird, verwenden Sie selectRange() für den begleitenden Text. Dies gewährleistet Konsistenz zwischen der Zahlenformatierung und der Textpluralisierung.
const locale = "en-US";
const numberFormat = new Intl.NumberFormat(locale);
const pluralRules = new Intl.PluralRules(locale);
const forms = new Map([
["one", "result"],
["other", "results"]
]);
function formatSearchResults(start, end) {
const rangeFormatted = numberFormat.formatRange(start, end);
const category = pluralRules.selectRange(start, end);
const form = forms.get(category);
return `Found ${rangeFormatted} ${form}`;
}
console.log(formatSearchResults(10, 15));
// Output: "Found 10–15 results"
Dieses Muster verwendet formatRange() aus Intl.NumberFormat, um die Zahlen zu formatieren, und selectRange() aus Intl.PluralRules, um den Text auszuwählen. Beide Methoden arbeiten mit Bereichen und gewährleisten eine korrekte Handhabung für alle Sprachen.