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

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

Introduction

Lorsque vous convertissez un tableau en chaîne de caractères lisible, vous devez séparer les éléments par 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 de caractères avec des séparateurs adaptés à la locale. Cela garantit que vos listes apparaissent naturelles pour les utilisateurs dans chaque langue.

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

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

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

// Anglais : "red, green, blue"

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

// Japonais : "赤、緑、青"

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

// Chinois : "红、绿、蓝"

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

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

Ces différences sont automatiquement gérées 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 de caractères 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 d'autres langues.

const colors = ["赤", "緑", "青"];
console.log(colors.join(", "));
// "赤, 緑, 青" (incorrect - devrait utiliser 、 au lieu de ,)

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

Utilisation d'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 la 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 ne maintenez aucun code spécifique à la 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 est formaté 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 automatiquement toutes ces différences. Vous écrivez le même code pour chaque langue.

Utilisation de 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 en français voit la ponctuation française. Un utilisateur avec des paramètres japonais voit la ponctuation japonaise.

Formatage des 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 d'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 d'unité utilise uniquement des séparateurs sans ajouter de mots de liaison. C'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. C'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 appropriés 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 devriez vérifier si un tableau est vide avant de le formater si vous avez besoin d'un comportement différent.

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

console.log(formatList([], "en"));
// "Aucun élément"

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 n'est pas pris en charge");
}

Pour les navigateurs plus anciens, vous pouvez vous rabattre sur 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" (ou "red, green, blue" dans les navigateurs plus anciens)

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