桁区切り記号を使用して数値をフォーマットする方法
JavaScriptを使用してロケールに適した区切り記号で大きな数値を表示する
はじめに
大きな数字は視覚的な区切りがないと読みにくいものです。1234567という数字が100万を表しているのか1000万を表しているのかを判断するには、注意深く数える必要があります。区切り記号を追加して1,234,567とすると、約100万であることがすぐに認識できます。
国によって数字のグループを区切るために使用する記号は異なります。アメリカ人はコンマを使用し、ドイツ人はピリオドを使用し、フランス語圏ではスペースを使用します。世界中の人々が使用するアプリケーションで数字を表示する場合、各ユーザーの期待に応じてそれらの数字を適切にフォーマットする必要があります。
JavaScriptは、これを自動的に処理するためのIntl.NumberFormat APIを提供しています。このレッスンでは、桁区切り記号の仕組み、ロケールによって異なる理由、そして任意の言語や地域に対して数字を正しくフォーマットする方法について説明します。
桁区切り記号とは
桁区切り記号は、大きな数字を読みやすくするために数字のグループ間に挿入される記号です。ほとんどのロケールでは、数字は右から左へ3桁ごとにグループ化されます。1234567という数字は、コンマ区切りを使用すると1,234,567になります。
「桁区切り記号」という用語は、3桁ごとに区切り記号が表示される最も一般的なユースケースに由来しています。ただし、同じメカニズムは、何十万、何百万、何十億であっても、あらゆる数字のグループ化に適用されます。
区切り記号がなければ、数字が連続して表示され、注意深く数える必要があります。区切り記号があれば、目で素早く数字の大きさを識別できます。この視覚的なグループ化により、読み取りエラーが減少し、理解度が向上します。
桁区切り記号がロケールによって異なる理由
異なる国々では、数字を書くための異なる慣習が確立されています。これらの慣習は、地域の印刷慣行、教育システム、文化的嗜好に基づいて独自に発展してきました。
アメリカ合衆国、イギリス、オーストラリアなどの英語圏の国々では、コンマが桁区切り記号として使用されます。100万という数字は1,000,000と表示されます。
ドイツ、イタリア、スペイン、ポルトガルなど多くのヨーロッパ諸国では、ピリオドが桁区切り記号として使用されます。同じ数字は1.000.000と表示されます。
フランスおよび多くのフランス語圏では、スペースが桁区切り記号として使用されます。この数字は1 000 000と表示されます。
スイスでは、アポストロフィが桁区切り記号として使用されます。この数字は1'000'000と表示されます。
インドのような国々では、異なるグループ化パターンを使用しています。インドの数字表記法では、最初の3桁をグループ化し、その後の数字を2桁ずつグループ化します。100万は、ラック(lakh)システムを使用して10,00,000と表示されます。
特定の区切り文字をハードコードすると、すべてのユーザーが同じ慣習に従っていると仮定することになります。これにより、異なる地域の人々にとってアプリケーションの使いやすさが低下します。
桁区切りを追加するための Intl.NumberFormat の使用
Intl.NumberFormat コンストラクタは、ロケール固有の規則を適用する数値フォーマッタを作成します。最初の引数としてロケール識別子を渡し、数値を指定して format() メソッドを呼び出します。
const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(1234567));
// 出力: "1,234,567"
これは米国英語用のフォーマッタを作成し、桁区切りにカンマを使用します。format() メソッドは数値を文字列に変換し、適切な区切り記号を挿入します。
ロケール識別子を変更することで、同じ数値を異なるロケール向けにフォーマットできます。
const usFormatter = new Intl.NumberFormat('en-US');
console.log(usFormatter.format(1234567));
// 出力: "1,234,567"
const deFormatter = new Intl.NumberFormat('de-DE');
console.log(deFormatter.format(1234567));
// 出力: "1.234.567"
const frFormatter = new Intl.NumberFormat('fr-FR');
console.log(frFormatter.format(1234567));
// 出力: "1 234 567"
各フォーマッタはそのロケールの規則を適用します。ドイツ語のフォーマッタはピリオドを使用し、フランス語のフォーマッタはスペースを使用し、米国のフォーマッタはカンマを使用します。各ロケールがどの記号を使用するかを知る必要はありません。APIがこれらの詳細を自動的に処理します。
ユーザーのロケールに合わせた数値のフォーマット
特定のロケールをハードコーディングする代わりに、ブラウザからユーザーの優先言語を使用できます。navigator.language プロパティはユーザーの最優先言語を返します。
const userLocale = navigator.language;
const formatter = new Intl.NumberFormat(userLocale);
console.log(formatter.format(1234567));
// 出力はユーザーのロケールによって異なります
// en-US の場合: "1,234,567"
// de-DE の場合: "1.234.567"
// fr-FR の場合: "1 234 567"
このアプローチでは、ユーザーが手動でロケールを選択する必要なく、各ユーザーの期待に応じた数値表示が可能になります。ブラウザが言語設定を提供し、Intl APIが適切なフォーマット規則を適用します。
フォールバック動作を有効にするために、優先言語の配列全体を渡すこともできます。
const formatter = new Intl.NumberFormat(navigator.languages);
console.log(formatter.format(1234567));
APIは配列から最初にサポートするロケールを使用します。これにより、ユーザーの最優先設定が利用できない場合に、より良いフォールバック処理が提供されます。
デフォルトのグループ化動作を理解する
デフォルトでは、Intl.NumberFormatはグループ化の恩恵を受けるのに十分な大きさのすべての数値に桁区切り記号を適用します。通常、4桁以上の数値には区切り記号が適用されますが、これはロケールによって異なります。
const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(123));
// 出力: "123"
console.log(formatter.format(1234));
// 出力: "1,234"
console.log(formatter.format(12345));
// 出力: "12,345"
console.log(formatter.format(123456));
// 出力: "123,456"
123のような小さな数値には区切り記号は必要なく、区切り記号なしで表示されます。1234以上の数値は、グループ化によって読みやすさが向上するため、区切り記号が適用されます。
APIはロケールの慣習に基づいて、区切り記号が有益な場合を自動的に判断します。フォーマット前に各数値の大きさを手動でチェックする必要はありません。
千の位区切り記号を使用した小数のフォーマット
Intl.NumberFormat APIは数値の整数部分と小数部分の両方を処理します。千の位区切り記号は整数部分に表示され、小数点と小数部分はロケールの慣習に従います。
const usFormatter = new Intl.NumberFormat('en-US');
console.log(usFormatter.format(1234567.89));
// 出力: "1,234,567.89"
const deFormatter = new Intl.NumberFormat('de-DE');
console.log(deFormatter.format(1234567.89));
// 出力: "1.234.567,89"
ドイツ語のフォーマットでは両方の慣習が逆になっていることに注目してください。ピリオドは整数部分の千の位区切り記号として機能し、カンマは小数部分の小数点として機能します。IntlのAPIはロケールに基づいて両方の側面を正しく処理します。
非常に大きな数値の処理
数値が大きくなるにつれて、千の位区切り記号はますます重要になります。区切り記号がなければ、7桁、8桁、または9桁の数値は一目で正確に読むことがほぼ不可能です。
const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(1234567890));
// 出力: "1,234,567,890"
console.log(formatter.format(9876543210));
// 出力: "9,876,543,210"
フォーマッターは3桁ごとに区切り記号を挿入し、10億単位の数値でも読みやすくします。この自動グループ化は、区切り記号の位置を手動で計算する必要なく、あらゆる大きさの数値に対して機能します。
パフォーマンス向上のためのフォーマッターの再利用
新しいIntl.NumberFormatインスタンスを作成すると、ロケールデータの読み込みとオプションの処理が行われます。同じロケールと設定で複数の数値をフォーマットする必要がある場合は、フォーマッターを一度作成して再利用してください。
const formatter = new Intl.NumberFormat('en-US');
const numbers = [1234, 5678, 91011, 121314];
numbers.forEach(number => {
console.log(formatter.format(number));
});
// 出力:
// "1,234"
// "5,678"
// "91,011"
// "121,314"
このアプローチは、数値ごとに新しいフォーマッターを作成するよりも効率的です。数百または数千の値を持つ配列をフォーマットする場合、パフォーマンスの差は顕著になります。
テンプレート内での数値のフォーマット
ユーザーに数値を表示するあらゆる場所でIntl.NumberFormatを使用できます。これには、HTMLテンプレートにフォーマットされた数値を挿入したり、テーブルに値を表示したり、ダッシュボードに統計を表示したりすることが含まれます。
const formatter = new Intl.NumberFormat(navigator.language);
const totalUsers = 1234567;
const activeUsers = 891234;
document.getElementById('total-users').textContent = formatter.format(totalUsers);
document.getElementById('active-users').textContent = formatter.format(activeUsers);
フォーマットされた文字列は他の文字列値と同様に機能します。テキストコンテンツ、属性、またはユーザーに情報を表示するその他のコンテキストに挿入できます。