Comment formater des tableaux avec des séparateurs spécifiques à la locale en JavaScript ?

Utilisez Intl.ListFormat pour appliquer automatiquement les virgules, espaces et ponctuation corrects pour n'importe quelle langue.

Introduction

Lorsque vous convertissez un tableau en chaîne lisible, vous devez séparer les éléments avec des virgules ou d'autres signes de ponctuation. Différentes langues utilisent différents séparateurs. L'anglais utilise des virgules et des espaces, le japonais utilise la virgule d'énumération 、, et l'arabe utilise une ponctuation et un ordre des mots différents.

L'API Intl.ListFormat convertit les tableaux en chaînes avec des séparateurs appropriés à la locale. Cela garantit que vos listes paraissent naturelles aux utilisateurs dans toutes les langues.

Pourquoi les séparateurs de tableaux diffèrent selon la locale

Vous pourriez supposer que toutes les langues utilisent des virgules pour séparer les éléments de liste. Ce n'est pas vrai.

L'anglais sépare les éléments avec une virgule et un espace.

// English: "red, green, blue"

Le japonais utilise la virgule d'énumération 、 sans espaces.

// Japanese: "赤、緑、青"

Le chinois utilise le même caractère de virgule d'énumération 、.

// Chinese: "红、绿、蓝"

L'arabe utilise un caractère de virgule différent، et se lit de droite à gauche.

// Arabic: "أحمر، أخضر، أزرق"

Ces différences sont automatiques dans Intl.ListFormat. Vous n'avez pas besoin de connaître les règles de ponctuation pour chaque langue.

Le problème avec join()

La méthode Array.prototype.join() convertit les tableaux en chaînes en utilisant un séparateur que vous spécifiez.

const colors = ["red", "green", "blue"];
console.log(colors.join(", "));
// "red, green, blue"

Cela code en dur la ponctuation anglaise. Le séparateur virgule et espace ne fonctionne pas pour les autres langues.

const colors = ["赤", "緑", "青"];
console.log(colors.join(", "));
// "赤, 緑, 青" (wrong - should use 、 instead of ,)

Vous ne pouvez pas changer manuellement les séparateurs en fonction de la locale car vous devriez maintenir une correspondance de chaque langue avec ses règles de ponctuation. Cette correspondance serait incomplète et difficile à maintenir.

Utiliser Intl.ListFormat pour des séparateurs adaptés à la locale

Le constructeur Intl.ListFormat crée un formateur qui applique les séparateurs corrects pour n'importe quelle locale.

const formatter = new Intl.ListFormat("en");
const colors = ["red", "green", "blue"];
console.log(formatter.format(colors));
// "red, green, and blue"

Le formateur utilise automatiquement la ponctuation appropriée pour la locale spécifiée. Vous passez le code de locale comme premier argument.

const enFormatter = new Intl.ListFormat("en");
const jaFormatter = new Intl.ListFormat("ja");
const arFormatter = new Intl.ListFormat("ar");

const colors = ["red", "green", "blue"];

console.log(enFormatter.format(colors));
// "red, green, and blue"

console.log(jaFormatter.format(["赤", "緑", "青"]));
// "赤、緑、青"

console.log(arFormatter.format(["أحمر", "أخضر", "أزرق"]));
// "أحمر، أخضر، أزرق"

Le navigateur fournit les règles de ponctuation. Vous n'avez pas à maintenir de code spécifique à une locale.

Comment les séparateurs changent selon les langues

Le formateur applique différents séparateurs en fonction de la locale. Ces exemples montrent comment le même tableau se formate différemment.

L'anglais utilise une virgule, un espace et le mot "and".

const formatter = new Intl.ListFormat("en");
console.log(formatter.format(["apple", "orange", "banana"]));
// "apple, orange, and banana"

L'espagnol utilise une virgule, un espace et le mot "y".

const formatter = new Intl.ListFormat("es");
console.log(formatter.format(["manzana", "naranja", "plátano"]));
// "manzana, naranja y plátano"

Le français utilise une virgule, un espace et le mot "et".

const formatter = new Intl.ListFormat("fr");
console.log(formatter.format(["pomme", "orange", "banane"]));
// "pomme, orange et banane"

L'allemand utilise une virgule, un espace et le mot "und".

const formatter = new Intl.ListFormat("de");
console.log(formatter.format(["Apfel", "Orange", "Banane"]));
// "Apfel, Orange und Banane"

Le japonais utilise la virgule d'énumération 、 et le caractère 、.

const formatter = new Intl.ListFormat("ja");
console.log(formatter.format(["りんご", "オレンジ", "バナナ"]));
// "りんご、オレンジ、バナナ"

Le chinois utilise la virgule d'énumération 、 et le mot 和.

const formatter = new Intl.ListFormat("zh");
console.log(formatter.format(["苹果", "橙子", "香蕉"]));
// "苹果、橙子和香蕉"

Le coréen utilise une virgule et la particule 및.

const formatter = new Intl.ListFormat("ko");
console.log(formatter.format(["사과", "오렌지", "바나나"]));
// "사과, 오렌지 및 바나나"

Le formateur gère toutes ces différences automatiquement. Vous écrivez le même code pour chaque langue.

Utiliser la locale de l'utilisateur

Vous pouvez détecter la locale préférée de l'utilisateur à partir des paramètres de son navigateur et l'utiliser pour formater les listes.

const userLocale = navigator.language;
const formatter = new Intl.ListFormat(userLocale);
const items = ["first", "second", "third"];
console.log(formatter.format(items));

Cela garantit que la liste utilise des séparateurs qui correspondent aux attentes de l'utilisateur. Un utilisateur avec des paramètres de navigateur français voit la ponctuation française. Un utilisateur avec des paramètres japonais voit la ponctuation japonaise.

Formatage de tableaux sans conjonctions

Le comportement par défaut de Intl.ListFormat ajoute une conjonction comme « et » avant le dernier élément. Vous pouvez désactiver cela en utilisant le type unit.

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

Le type unit utilise uniquement des séparateurs sans ajouter de mots de liaison. Cela est utile pour les listes techniques, les mesures ou les données où les conjonctions ne sont pas appropriées.

const enFormatter = new Intl.ListFormat("en", { type: "unit" });
const jaFormatter = new Intl.ListFormat("ja", { type: "unit" });

console.log(enFormatter.format(["Item A", "Item B", "Item C"]));
// "Item A, Item B, Item C"

console.log(jaFormatter.format(["項目A", "項目B", "項目C"]));
// "項目A、項目B、項目C"

Même sans conjonctions, la ponctuation des séparateurs suit toujours les règles de la locale.

Création de formateurs réutilisables

Vous pouvez créer un formateur une fois et le réutiliser pour plusieurs tableaux. Cela est plus efficace que de créer un nouveau formateur pour chaque tableau.

const formatter = new Intl.ListFormat("en");

console.log(formatter.format(["red", "green"]));
// "red and green"

console.log(formatter.format(["a", "b", "c", "d"]));
// "a, b, c, and d"

console.log(formatter.format(["one"]));
// "one"

Le même formateur fonctionne pour des tableaux de n'importe quelle longueur. Il applique les séparateurs et conjonctions corrects en fonction du nombre d'éléments dans le tableau.

Gestion des tableaux vides

Lorsque vous formatez un tableau vide, le formateur renvoie une chaîne vide.

const formatter = new Intl.ListFormat("en");
console.log(formatter.format([]));
// ""

Vous devez vérifier les tableaux vides avant le formatage si vous avez besoin d'un comportement différent.

function formatList(items, locale) {
  if (items.length === 0) {
    return "No items";
  }
  const formatter = new Intl.ListFormat(locale);
  return formatter.format(items);
}

console.log(formatList([], "en"));
// "No items"

console.log(formatList(["apple"], "en"));
// "apple"

Cela vous donne le contrôle sur la façon dont les tableaux vides apparaissent aux utilisateurs.

Compatibilité des navigateurs

L'API Intl.ListFormat est disponible dans tous les navigateurs modernes. Elle est prise en charge depuis avril 2021 sur Chrome, Firefox, Safari et Edge.

Vous pouvez vérifier si l'API existe 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 is not supported");
}

Pour les navigateurs plus anciens, vous pouvez revenir à la méthode join(). Cela fournit un formatage de base sans séparateurs spécifiques à la locale.

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)

Cela garantit que votre code fonctionne sur tous les navigateurs tout en offrant la meilleure expérience sur les navigateurs modernes.