Wie formatiere ich Listen wie A, B und C in JavaScript?

Nutze Intl.ListFormat, um Arrays mit sprachspezifischen Konjunktionen und Trennzeichen zu formatieren.

Einführung

Wenn du eine Liste von Elementen für Nutzer anzeigst, musst du sie mit Kommas und einer Konjunktion wie "und" verbinden. Verschiedene Sprachen haben dafür verschiedene Konventionen. Englisch verwendet Kommas und "and", Spanisch nutzt "y", Französisch verwendet "et" und Chinesisch verwendet ganz andere Satzzeichen.

Die Intl.ListFormat API formatiert Arrays als lokalisierte Strings mit den richtigen Trennzeichen und Konjunktionen. Damit werden die kulturellen Unterschiede bei der Listenformatierung automatisch berücksichtigt.

Das Problem mit manueller Listenformatierung

Du kannst Array-Elemente mit Kommas verbinden, indem du die Methode join() verwendest.

const fruits = ["apples", "oranges", "bananas"];
const list = fruits.join(", ");
console.log(list);
// "apples, oranges, bananas"

Diese Vorgehensweise hat zwei Probleme. Erstens wird keine Konjunktion vor dem letzten Element eingefügt. Zweitens werden englische Satzzeichen genutzt, die in anderen Sprachen nicht funktionieren.

Du könntest "and" vor dem letzten Element manuell hinzufügen.

const fruits = ["apples", "oranges", "bananas"];
const lastFruit = fruits[fruits.length - 1];
const otherFruits = fruits.slice(0, -1);
const list = otherFruits.join(", ") + ", and " + lastFruit;
console.log(list);
// "apples, oranges, and bananas"

Dieser Code funktioniert nur für Englisch. Spanische Nutzer würden "apples, oranges, and bananas" sehen, anstatt "apples, oranges y bananas". Französische Nutzer würden "and" anstelle von "et" sehen. Die Regeln für Satzzeichen und Konjunktionen unterscheiden sich je nach Sprache.

Listen mit Intl.ListFormat formatieren

Der Intl.ListFormat Konstruktor erstellt einen Formatter, der Arrays in sprachspezifische Listen-Strings umwandelt.

const formatter = new Intl.ListFormat("en");
const fruits = ["apples", "oranges", "bananas"];
console.log(formatter.format(fruits));
// "apples, oranges, and bananas"

Der Formatter verwendet die richtigen Trennzeichen und Konjunktionen für die angegebene Sprache. Du gibst die Locale als erstes Argument an den Konstruktor weiter.

const enFormatter = new Intl.ListFormat("en");
const esFormatter = new Intl.ListFormat("es");
const frFormatter = new Intl.ListFormat("fr");

const fruits = ["apples", "oranges", "bananas"];

console.log(enFormatter.format(fruits));
// "apples, oranges, and bananas"

console.log(esFormatter.format(fruits));
// "apples, oranges y bananas"

console.log(frFormatter.format(fruits));
// "apples, oranges et bananas"

Der Formatter setzt die Regeln für Satzzeichen und Konjunktionen für jede Sprache automatisch um.

Listen mit "und" formatieren

Das Standardverhalten von Intl.ListFormat verwendet die Konjunktion "und" (bzw. das jeweilige Pendant in anderen Sprachen). Dies wird als Konjunktions-Formatierung bezeichnet.

const formatter = new Intl.ListFormat("en", { type: "conjunction" });
const items = ["bread", "milk", "eggs"];
console.log(formatter.format(items));
// "bread, milk, and eggs"

Mit der Option type wird bestimmt, welcher Verbinder zwischen den Elementen erscheint. Der Wert "conjunction" erzeugt Listen mit „und“. Das ist der Standardwert, daher kannst du ihn weglassen.

Listen-Typen verstehen

Die Option type akzeptiert drei Werte, die steuern, wie Elemente miteinander verbunden werden.

Der Typ "conjunction" verwendet „und“ oder eine entsprechende Entsprechung.

const formatter = new Intl.ListFormat("en", { type: "conjunction" });
console.log(formatter.format(["red", "green", "blue"]));
// "red, green, and blue"

Der Typ "disjunction" verwendet „oder“ oder eine entsprechende Entsprechung.

const formatter = new Intl.ListFormat("en", { type: "disjunction" });
console.log(formatter.format(["red", "green", "blue"]));
// "red, green, or blue"

Der Typ "unit" formatiert Listen mit Maßeinheiten oder Mengenangaben ohne Konjunktion.

const formatter = new Intl.ListFormat("en", { type: "unit" });
console.log(formatter.format(["5 pounds", "12 ounces"]));
// "5 pounds, 12 ounces"

Beim Unit-Typ wird minimale Interpunktion verwendet, passend für technische Daten oder Messwerte.

Formatierungsstile verstehen

Mit der Option style steuerst du Länge und Formalität der Ausgabe. Es gibt drei Werte.

Der Stil "long" verwendet ausgeschriebene Wörter und Standardzeichensetzung. Das ist der Standard.

const formatter = new Intl.ListFormat("en", { style: "long" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, and Carol"

Der Stil "short" verwendet, wenn möglich, Abkürzungen.

const formatter = new Intl.ListFormat("en", { style: "short" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, & Carol"

Der Stil "narrow" nutzt die kompakteste Form.

const formatter = new Intl.ListFormat("en", { style: "narrow" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, Carol"

Bei der engen Formatierung wird die Konjunktion oft komplett weggelassen. Die genaue Ausgabe hängt vom jeweiligen Sprachraum ab.

Wie verschiedene Sprachräume Listen formatieren

Jeder Sprachraum hat eigene Regeln zur Listenformatierung. Der Formatter berücksichtigt diese automatisch.

Im Englischen werden Kommas verwendet und das sogenannte Oxford-Komma steht vor „and“.

const formatter = new Intl.ListFormat("en");
console.log(formatter.format(["coffee", "tea", "juice"]));
// "coffee, tea, and juice"

Im Spanischen werden Kommas und die Konjunktion „y“ verwendet.

const formatter = new Intl.ListFormat("es");
console.log(formatter.format(["café", "té", "jugo"]));
// "café, té y jugo"

Im Französischen werden Kommas und die Konjunktion "et" verwendet.

const formatter = new Intl.ListFormat("fr");
console.log(formatter.format(["café", "thé", "jus"]));
// "café, thé et jus"

Im Chinesischen wird das Zeichen 和 für "und" und das Aufzählungszeichen 、 als Trennzeichen verwendet.

const formatter = new Intl.ListFormat("zh");
console.log(formatter.format(["咖啡", "茶", "可乐"]));
// "咖啡、茶和可乐"

Im Deutschen werden Kommas und die Konjunktion "und" verwendet.

const formatter = new Intl.ListFormat("de");
console.log(formatter.format(["Kaffee", "Tee", "Saft"]));
// "Kaffee, Tee und Saft"

Der Formatter berücksichtigt diese Unterschiede automatisch, ohne dass du die Regeln jeder Sprache kennen musst.

Einzelteile mit formatToParts erhalten

Die Methode formatToParts() gibt ein Array von Objekten zurück, die jeweils einen Teil der formatierten Liste repräsentieren. Das ist nützlich, wenn du einzelne Teile unterschiedlich stylen möchtest.

const formatter = new Intl.ListFormat("en");
const parts = formatter.formatToParts(["red", "green", "blue"]);
console.log(parts);

Das Ergebnis ist ein Array von Objekten mit den Eigenschaften type und value.

[
  { type: "element", value: "red" },
  { type: "literal", value: ", " },
  { type: "element", value: "green" },
  { type: "literal", value: ", and " },
  { type: "element", value: "blue" }
]

Jedes Listenelement hat den Typ "element". Die Trennzeichen und Konjunktionen haben den Typ "literal". So kannst du eigenes Styling anwenden.

const formatter = new Intl.ListFormat("en");
const parts = formatter.formatToParts(["red", "green", "blue"]);

const html = parts
  .map((part) => {
    if (part.type === "element") {
      return `<strong>${part.value}</strong>`;
    }
    return part.value;
  })
  .join("");

console.log(html);
// "<strong>red</strong>, <strong>green</strong>, and <strong>blue</strong>"

Mit diesem Ansatz behältst du die volle Kontrolle über das Formatieren und stellst gleichzeitig sicher, dass die Trennzeichen und Konjunktionen passend zur jeweiligen Sprache sind.

Browser-Unterstützung

Die API Intl.ListFormat ist in allen modernen Browsern verfügbar. Sie wird seit April 2021 von allen großen Browsern wie Chrome, Firefox, Safari und Edge unterstützt.

Du kannst vor der Nutzung prüfen, ob die API verfügbar ist.

if (typeof Intl.ListFormat !== "undefined") {
  const formatter = new Intl.ListFormat("en");
  console.log(formatter.format(["a", "b", "c"]));
} else {
  console.log("Intl.ListFormat is not supported");
}

Für ältere Browser solltest du ein Fallback anbieten oder einen Polyfill verwenden. Als Fallback kannst du die einfache Methode join() nutzen.

function formatList(items, locale) {
  if (typeof Intl.ListFormat !== "undefined") {
    const formatter = new Intl.ListFormat(locale);
    return formatter.format(items);
  }
  return items.join(", ");
}

console.log(formatList(["red", "green", "blue"], "en"));
// "red, green, and blue" (or "red, green, blue" in older browsers)

So stellst du sicher, dass dein Code auch in Browsern ohne Unterstützung für Intl.ListFormat funktioniert.