Comment supprimer les informations redondantes des identifiants de locale

Utilisez la méthode minimize pour créer des identifiants de locale compacts sans perdre de sens

Introduction

Les identifiants de locale comme en-Latn-US et zh-Hans-CN contiennent plusieurs composants qui spécifient la langue, l'écriture et la région. Cependant, tous ces composants ne sont pas nécessaires pour identifier une locale. Certains composants sont redondants car ils peuvent être déduits d'autres parties de l'identifiant.

La méthode minimize() supprime ces composants redondants pour créer l'identifiant de locale équivalent le plus court. Cela produit des identifiants compacts qui préservent le sens tout en réduisant la taille de stockage et en améliorant la lisibilité.

Comprendre la redondance dans les identifiants de locale

Un identifiant de locale devient redondant lorsqu'il indique explicitement des informations déjà implicites dans d'autres composants. La redondance se produit car chaque langue possède des valeurs par défaut probables pour l'écriture et la région.

Considérez l'identifiant en-Latn-US. Cet identifiant spécifie :

  • Langue : anglais (en)
  • Écriture : latin (Latn)
  • Région : États-Unis (US)

L'anglais s'écrit uniquement en écriture latine, et lorsqu'aucune région n'est spécifiée, l'anglais correspond par défaut aux États-Unis. Les composants d'écriture et de région sont redondants car ils correspondent aux valeurs par défaut probables pour l'anglais. L'identifiant en transmet la même information.

Le même principe s'applique aux autres langues. Le coréen (ko) s'écrit en écriture hangul (Kore) et est principalement parlé en Corée du Sud (KR). L'identifiant ko-Kore-KR contient des informations redondantes car ko seul implique ces valeurs par défaut.

Comment fonctionne la méthode minimize

La méthode minimize() est disponible sur les instances Intl.Locale. Elle analyse l'identifiant de locale et supprime les composants qui correspondent aux valeurs par défaut probables.

const locale = new Intl.Locale("en-Latn-US");
const minimized = locale.minimize();

console.log(minimized.baseName);
// Output: "en"

La méthode renvoie une nouvelle instance Intl.Locale avec les sous-balises redondantes supprimées. Elle ne modifie pas l'objet locale d'origine.

Le processus de minimisation suit l'algorithme Unicode CLDR « Remove Likely Subtags ». Cet algorithme utilise une base de données d'associations de sous-balises probables pour déterminer quels composants peuvent être supprimés sans perte d'information.

Composants affectés par minimize

La méthode minimize() affecte uniquement les composants principaux de la locale : langue, script et région. Elle ne supprime ni ne modifie les sous-balises d'extension Unicode qui spécifient les préférences de formatage.

const locale = new Intl.Locale("en-Latn-US-u-ca-gregory-nu-latn");
const minimized = locale.minimize();

console.log(minimized.toString());
// Output: "en-u-ca-gregory-nu-latn"

Les extensions de calendrier (ca-gregory) et de système de numération (nu-latn) restent intactes. Seuls les composants redondants de script (Latn) et de région (US) sont supprimés.

Exemples de minimisation

Différents identifiants de locale se minimisent à différentes longueurs selon les composants qui sont redondants.

Suppression du script et de la région

Lorsque le script et la région correspondent aux valeurs par défaut, les deux sont supprimés :

const english = new Intl.Locale("en-Latn-US");
console.log(english.minimize().baseName);
// Output: "en"

const korean = new Intl.Locale("ko-Kore-KR");
console.log(korean.minimize().baseName);
// Output: "ko"

const japanese = new Intl.Locale("ja-Jpan-JP");
console.log(japanese.minimize().baseName);
// Output: "ja"

Conservation des régions non par défaut

Lorsque la région diffère de la valeur par défaut, elle reste dans l'identifiant minimisé :

const britishEnglish = new Intl.Locale("en-Latn-GB");
console.log(britishEnglish.minimize().baseName);
// Output: "en-GB"

const canadianFrench = new Intl.Locale("fr-Latn-CA");
console.log(canadianFrench.minimize().baseName);
// Output: "fr-CA"

const mexicanSpanish = new Intl.Locale("es-Latn-MX");
console.log(mexicanSpanish.minimize().baseName);
// Output: "es-MX"

Le composant de script est supprimé car il correspond à la valeur par défaut, mais la région est préservée car elle spécifie une variante non par défaut de la langue.

Conservation des scripts non par défaut

Lorsque le script diffère de la valeur par défaut, il reste dans l'identifiant minimisé :

const simplifiedChinese = new Intl.Locale("zh-Hans-CN");
console.log(simplifiedChinese.minimize().baseName);
// Output: "zh-Hans"

const traditionalChinese = new Intl.Locale("zh-Hant-TW");
console.log(traditionalChinese.minimize().baseName);
// Output: "zh-Hant"

const serbianCyrillic = new Intl.Locale("sr-Cyrl-RS");
console.log(serbianCyrillic.minimize().baseName);
// Output: "sr-Cyrl"

Le chinois nécessite le composant de script pour distinguer les variantes simplifiée et traditionnelle. Le serbe nécessite le composant de script pour distinguer les écritures cyrillique et latine.

Identifiants déjà minimaux

Lorsqu'un identifiant de locale est déjà minimal, la méthode renvoie une locale équivalente sans modifications :

const minimal = new Intl.Locale("fr");
console.log(minimal.minimize().baseName);
// Output: "fr"

Relation avec maximize

La méthode minimize() est l'inverse de maximize(). La méthode maximize() ajoute des sous-balises probables pour créer un identifiant complet, tandis que minimize() supprime les sous-balises redondantes pour créer un identifiant compact.

Ces méthodes forment une paire qui permet la conversion bidirectionnelle entre les formes complètes et compactes :

const compact = new Intl.Locale("en");
const complete = compact.maximize();
console.log(complete.baseName);
// Output: "en-Latn-US"

const compactAgain = complete.minimize();
console.log(compactAgain.baseName);
// Output: "en"

L'aller-retour de la forme compacte à la forme complète puis de nouveau à la forme compacte produit la forme originale.

Cependant, toutes les locales ne reviennent pas à leur forme originale exacte après un aller-retour. La méthode produit une forme minimale canonique plutôt que de préserver la structure originale :

const locale = new Intl.Locale("en-US");
const maximized = locale.maximize();
console.log(maximized.baseName);
// Output: "en-Latn-US"

const minimized = maximized.minimize();
console.log(minimized.baseName);
// Output: "en"

L'identifiant original en-US contenait une région non redondante, mais après maximisation et minimisation, il devient en. Cela se produit parce que les États-Unis sont la région par défaut probable pour l'anglais.

Quand utiliser minimize

Utilisez minimize() lorsque vous avez besoin d'identifiants de locale compacts qui restent non ambigus. Plusieurs scénarios bénéficient de la minimisation.

Stocker les préférences de locale

Les identifiants minimisés réduisent l'espace de stockage dans les bases de données, le stockage local ou les fichiers de configuration :

function saveUserLocale(localeString) {
  const locale = new Intl.Locale(localeString);
  const minimized = locale.minimize().toString();

  localStorage.setItem("userLocale", minimized);
}

saveUserLocale("en-Latn-US");
// Stores "en" instead of "en-Latn-US"

Cela réduit la taille des données stockées sans perte d'information.

Créer des URL lisibles

Les identifiants minimisés produisent des URL plus propres pour la sélection de langue :

function createLocalizedURL(path, localeString) {
  const locale = new Intl.Locale(localeString);
  const minimized = locale.minimize().baseName;

  return `/${minimized}${path}`;
}

const url = createLocalizedURL("/products", "en-Latn-US");
console.log(url);
// Output: "/en/products"

L'URL /en/products est plus lisible que /en-Latn-US/products.

Comparer les identifiants de locale

La minimisation aide à déterminer si deux identifiants de locale représentent la même locale :

function areLocalesEquivalent(locale1String, locale2String) {
  const locale1 = new Intl.Locale(locale1String).minimize();
  const locale2 = new Intl.Locale(locale2String).minimize();

  return locale1.toString() === locale2.toString();
}

console.log(areLocalesEquivalent("en", "en-Latn-US"));
// Output: true

console.log(areLocalesEquivalent("en-US", "en-Latn-US"));
// Output: true

console.log(areLocalesEquivalent("en-US", "en-GB"));
// Output: false

La minimisation produit une forme canonique qui permet la comparaison directe.

Normaliser les entrées utilisateur

Lors de l'acceptation d'identifiants de locale provenant d'utilisateurs ou de systèmes externes, minimisez-les vers une forme standard :

function normalizeLocale(localeString) {
  try {
    const locale = new Intl.Locale(localeString);
    return locale.minimize().toString();
  } catch (error) {
    return null;
  }
}

console.log(normalizeLocale("en-US"));
// Output: "en"

console.log(normalizeLocale("en-Latn-US"));
// Output: "en"

console.log(normalizeLocale("en-GB"));
// Output: "en-GB"

Cette fonction accepte diverses formes de la même locale et retourne une représentation cohérente.

Combiner minimize avec d'autres opérations de locale

La méthode minimize() fonctionne avec d'autres fonctionnalités Intl.Locale pour créer une gestion flexible des locales.

Minimiser après modification des propriétés de locale

Lors de la construction d'une locale à partir de composants, minimisez-la pour supprimer les parties inutiles :

const locale = new Intl.Locale("en", {
  region: "US",
  script: "Latn"
});

const minimized = locale.minimize();
console.log(minimized.baseName);
// Output: "en"

Cela garantit que l'identifiant final est aussi compact que les composants d'entrée le permettent.

Préserver les extensions lors de la minimisation

Les extensions restent intactes pendant la minimisation, vous permettant de minimiser les composants principaux tout en conservant les préférences de formatage :

function createCompactLocaleWithPreferences(language, region, preferences) {
  const locale = new Intl.Locale(language, {
    region: region,
    ...preferences
  });

  return locale.minimize().toString();
}

const localeString = createCompactLocaleWithPreferences("en", "US", {
  hourCycle: "h23",
  calendar: "gregory"
});

console.log(localeString);
// Output: "en-u-ca-gregory-hc-h23"

Les composants principaux se minimisent en en, mais les extensions de calendrier et de cycle horaire demeurent.