Intl.PluralRules

公開 · タグ:Intl

インタナショナリゼーションは難しいです。複数形を処理することは、すべての言語に独自の数化ルールがあることに気付くまでは、単純に見える多くの問題の 1 つです。

英語の数化では、2 つの結果のみが考えられます。例として「cat」という単語を使用してみましょう

  • 1 cat、つまり単数形として知られる'one'形式。これは英語における単数。
  • 2 cats、さらに 42 cats、0.5 cats など、つまり'other'(唯一の他の)形式で、英語の数としては複数です。

真新しいIntl.PluralRules APIがある言語で、指定された数に基づいてどの形式を適用するかを教示します。

const pr = new Intl.PluralRules('en-US');
pr.select(0); // 'other' (e.g. '0 cats')
pr.select(0.5); // 'other' (e.g. '0.5 cats')
pr.select(1); // 'one' (e.g. '1 cat')
pr.select(1.5); // 'other' (e.g. '0.5 cats')
pr.select(2); // 'other' (e.g. '0.5 cats')

他のインタナショナリゼーション API とは異なり、Intl.PluralRulesは低レベルの API で、それ自体は何もフォーマットを実行しません。ただし、その上に独自のフォーマッタを構築できます

const suffixes = new Map([
// Note: in real-world scenarios, you wouldn’t hardcode the plurals
// like this; they’d be part of your translation files.
['one', 'cat'],
['other', 'cats'],
]);
const pr = new Intl.PluralRules('en-US');
const formatCats = (n) => {
const rule = pr.select(n);
const suffix = suffixes.get(rule);
return `${n} ${suffix}`;
};

formatCats(1); // '1 cat'
formatCats(0); // '0 cats'
formatCats(0.5); // '0.5 cats'
formatCats(1.5); // '1.5 cats'
formatCats(2); // '2 cats'

比較的単純な英語の数化ルールの場合、これはやり過ぎのように思えるかもしれません。ただし、すべての言語が同じルールに従っているわけではありません。単数形の形式は 1 つしかなく、複数形の形式が複数ある言語もあります。たとえばウェールズ語には 6 つの異なる数化形式があります!

const suffixes = new Map([
['zero', 'cathod'],
['one', 'gath'],
// Note: the `two` form happens to be the same as the `'one'`
// form for this word specifically, but that is not true for
// all words in Welsh.
['two', 'gath'],
['few', 'cath'],
['many', 'chath'],
['other', 'cath'],
]);
const pr = new Intl.PluralRules('cy');
const formatWelshCats = (n) => {
const rule = pr.select(n);
const suffix = suffixes.get(rule);
return `${n} ${suffix}`;
};

formatWelshCats(0); // '0 cathod'
formatWelshCats(1); // '1 gath'
formatWelshCats(1.5); // '1.5 cath'
formatWelshCats(2); // '2 gath'
formatWelshCats(3); // '3 cath'
formatWelshCats(6); // '6 chath'
formatWelshCats(42); // '42 cath'

複数の言語をサポートしながら正しい数化を実装するには、言語とその数化ルールのデータベースが必要です。ユニコード CLDRにはこのデータが含まれますが、JavaScript で使用するには、埋め込まれて他の JavaScript コードと一緒に配布する必要があり、読み込み時間、解析時間、メモリ使用量が長くなります。Intl.PluralRules API がその負担を JavaScript エンジンに移し、さらに高性能な国際化数値を実現します。

注: CLDR データには言語ごとのフォームマッピングが含まれますが、個々の単語の単数/複数フォームのリストは含まれません。以前と同様に、翻訳して自分で提供する必要があります。

序数 #

Intl.PluralRules API は、オプションのoptions引数のtypeプロパティを介して、さまざまなセレクタルールをサポートしています。暗黙のデフォルト値(上記で例で使用されている)は'cardinal'です。代わりに、特定の数(例: 11st22ndなど)の序数インジケータを把握するには、{ type: 'ordinal' }を使用します

const pr = new Intl.PluralRules('en-US', {
type: 'ordinal'
});
const suffixes = new Map([
['one', 'st'],
['two', 'nd'],
['few', 'rd'],
['other', 'th'],
]);
const formatOrdinals = (n) => {
const rule = pr.select(n);
const suffix = suffixes.get(rule);
return `${n}${suffix}`;
};

formatOrdinals(0); // '0th'
formatOrdinals(1); // '1st'
formatOrdinals(2); // '2nd'
formatOrdinals(3); // '3rd'
formatOrdinals(4); // '4th'
formatOrdinals(11); // '11th'
formatOrdinals(21); // '21st'
formatOrdinals(42); // '42nd'
formatOrdinals(103); // '103rd'

Intl.PluralRulesは、特に他の国際化機能と比較すると、低レベルの API です。それが、直接使用しなくても、それを依存とするライブラリまたはフレームワークを使用する場合があります。

この API の利用が広まるにつれて、ハードコードされた CLDR データベースへの依存関係をネイティブ機能に置き換えるGlobalizeなどのライブラリが見つかります。これにより、読み込み時間パフォーマンス、解析時間パフォーマンス、ランタイムパフォーマンス、メモリ使用量を向上させることができます。

Intl.PluralRulesサポート #