Comment formater des listes comme A, B et C en JavaScript ?
Utilisez Intl.ListFormat pour formater des tableaux avec des conjonctions et des séparateurs spécifiques à la locale.
Introduction
Lorsque vous affichez une liste d'éléments aux utilisateurs, vous devez les joindre avec des virgules et une conjonction comme « et ». Différentes langues ont différentes conventions pour le formatage des listes. L'anglais utilise des virgules et « and », l'espagnol utilise « y », le français utilise « et », et le chinois utilise une ponctuation entièrement différente.
L'API Intl.ListFormat formate les tableaux en chaînes de caractères adaptées à la locale avec les séparateurs et conjonctions appropriés. Cela gère automatiquement les différences culturelles dans le formatage des listes.
Le problème avec le formatage manuel des listes
Vous pouvez joindre des éléments de tableau avec des virgules en utilisant la méthode join().
const fruits = ["pommes", "oranges", "bananes"];
const list = fruits.join(", ");
console.log(list);
// "pommes, oranges, bananes"
Cette approche présente deux problèmes. Premièrement, elle n'ajoute pas de conjonction avant le dernier élément. Deuxièmement, elle utilise une ponctuation anglaise qui ne fonctionne pas pour d'autres langues.
Vous pourriez ajouter manuellement « et » avant le dernier élément.
const fruits = ["pommes", "oranges", "bananes"];
const lastFruit = fruits[fruits.length - 1];
const otherFruits = fruits.slice(0, -1);
const list = otherFruits.join(", ") + " et " + lastFruit;
console.log(list);
// "pommes, oranges et bananes"
Ce code ne fonctionne que pour le français. Les utilisateurs espagnols verraient "pommes, oranges et bananes" au lieu de "pommes, oranges y bananes". Les utilisateurs anglais verraient "et" au lieu de "and". Les règles de ponctuation et de conjonction varient selon la langue.
Utilisation d'Intl.ListFormat pour formater les listes
Le constructeur Intl.ListFormat crée un formateur qui convertit les tableaux en chaînes de liste appropriées à la locale.
const formatter = new Intl.ListFormat("fr");
const fruits = ["pommes", "oranges", "bananes"];
console.log(formatter.format(fruits));
// "pommes, oranges et bananes"
Le formateur utilise les séparateurs et la conjonction corrects pour la locale spécifiée. Vous passez la locale comme premier argument au constructeur.
const enFormatter = new Intl.ListFormat("en");
const esFormatter = new Intl.ListFormat("es");
const frFormatter = new Intl.ListFormat("fr");
const fruits = ["pommes", "oranges", "bananes"];
console.log(enFormatter.format(fruits));
// "pommes, oranges, and bananes"
console.log(esFormatter.format(fruits));
// "pommes, oranges y bananes"
console.log(frFormatter.format(fruits));
// "pommes, oranges et bananes"
Le formateur applique automatiquement les règles de ponctuation et de conjonction pour chaque locale.
Formatage des listes avec "et"
Le comportement par défaut de Intl.ListFormat utilise la conjonction "et" ou son équivalent dans d'autres langues. C'est ce qu'on appelle le formatage par conjonction.
const formatter = new Intl.ListFormat("en", { type: "conjunction" });
const items = ["bread", "milk", "eggs"];
console.log(formatter.format(items));
// "bread, milk, and eggs"
L'option type contrôle quel connecteur apparaît entre les éléments. La valeur "conjunction" produit des listes qui utilisent "et". C'est la valeur par défaut, donc vous pouvez l'omettre.
Comprendre les options de type de liste
L'option type accepte trois valeurs qui contrôlent comment les éléments se connectent.
Le type "conjunction" utilise "et" ou son équivalent.
const formatter = new Intl.ListFormat("en", { type: "conjunction" });
console.log(formatter.format(["red", "green", "blue"]));
// "red, green, and blue"
Le type "disjunction" utilise "ou" ou son équivalent.
const formatter = new Intl.ListFormat("en", { type: "disjunction" });
console.log(formatter.format(["red", "green", "blue"]));
// "red, green, or blue"
Le type "unit" formate des listes de mesures ou de quantités sans conjonction.
const formatter = new Intl.ListFormat("en", { type: "unit" });
console.log(formatter.format(["5 pounds", "12 ounces"]));
// "5 pounds, 12 ounces"
Le type unit utilise une ponctuation minimale appropriée pour les données techniques ou de mesure.
Comprendre les options de style
L'option style contrôle la longueur et la formalité de la sortie formatée. Elle accepte trois valeurs.
Le style "long" utilise des mots complets et une ponctuation standard. C'est le style par défaut.
const formatter = new Intl.ListFormat("en", { style: "long" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, and Carol"
Le style "short" utilise des formes abrégées lorsqu'elles sont disponibles.
const formatter = new Intl.ListFormat("en", { style: "short" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, & Carol"
Le style "narrow" utilise la forme la plus compacte possible.
const formatter = new Intl.ListFormat("en", { style: "narrow" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, Carol"
Le style narrow omet souvent complètement la conjonction. La sortie exacte dépend de la locale.
Comment les différentes locales formatent les listes
Chaque locale a ses propres règles pour le formatage des listes. Le formateur applique ces règles automatiquement.
L'anglais utilise des virgules et inclut la virgule d'Oxford avant "and".
const formatter = new Intl.ListFormat("en");
console.log(formatter.format(["coffee", "tea", "juice"]));
// "coffee, tea, and juice"
L'espagnol utilise des virgules et la conjonction "y".
const formatter = new Intl.ListFormat("es");
console.log(formatter.format(["café", "té", "jugo"]));
// "café, té y jugo"
Le français utilise des virgules et la conjonction "et".
const formatter = new Intl.ListFormat("fr");
console.log(formatter.format(["café", "thé", "jus"]));
// "café, thé et jus"
Le chinois utilise le caractère 和 pour "et" et la virgule d'énumération 、 comme séparateur.
const formatter = new Intl.ListFormat("zh");
console.log(formatter.format(["咖啡", "茶", "可乐"]));
// "咖啡、茶和可乐"
L'allemand utilise des virgules et la conjonction "und".
const formatter = new Intl.ListFormat("de");
console.log(formatter.format(["Kaffee", "Tee", "Saft"]));
// "Kaffee, Tee und Saft"
Le formateur gère ces différences sans que vous ayez besoin de connaître les règles pour chaque langue.
Obtenir des parties individuelles avec formatToParts
La méthode formatToParts() renvoie un tableau d'objets représentant chaque partie de la liste formatée. Cela est utile lorsque vous devez styliser différentes parties séparément.
const formatter = new Intl.ListFormat("en");
const parts = formatter.formatToParts(["red", "green", "blue"]);
console.log(parts);
Le résultat est un tableau d'objets avec les propriétés type et value.
[
{ type: "element", value: "red" },
{ type: "literal", value: ", " },
{ type: "element", value: "green" },
{ type: "literal", value: ", and " },
{ type: "element", value: "blue" }
]
Chaque élément de la liste a le type "element". Les séparateurs et les conjonctions ont le type "literal". Vous pouvez utiliser cela pour appliquer un style personnalisé.
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>"
Cette approche vous donne un contrôle précis sur le formatage tout en maintenant des séparateurs et des conjonctions appropriés à la locale.
Compatibilité des navigateurs
L'API Intl.ListFormat est disponible dans tous les navigateurs modernes. Elle est prise en charge depuis avril 2021 sur les principaux navigateurs, notamment Chrome, Firefox, Safari et Edge.
Vous pouvez vérifier si l'API est disponible avant de l'utiliser.
if (typeof Intl.ListFormat !== "undefined") {
const formatter = new Intl.ListFormat("en");
console.log(formatter.format(["a", "b", "c"]));
} else {
console.log("Intl.ListFormat n'est pas pris en charge");
}
Pour les navigateurs plus anciens, vous devez fournir une solution de repli ou utiliser un polyfill. La solution de repli peut utiliser la simple méthode join().
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" (ou "red, green, blue" dans les navigateurs plus anciens)
Cela garantit que votre code fonctionne même dans les navigateurs sans prise en charge de Intl.ListFormat.