桁区切り記号を使用して数値を書式設定する方法
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万はラークシステムを使用して10,00,000と表記されます。
特定の区切り文字をハードコードすると、すべてのユーザーが同じ慣習に従うことを前提としてしまいます。これにより、異なる地域のユーザーにとってアプリケーションが使いにくくなります。
Intl.NumberFormatを使用した桁区切り記号の追加
Intl.NumberFormatコンストラクタは、ロケール固有の慣習を適用する数値フォーマッタを作成します。最初の引数としてロケール識別子を渡し、次に数値を指定してformat()メソッドを呼び出します。
const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(1234567));
// Output: "1,234,567"
これにより、カンマを桁区切り記号として使用する米国英語用のフォーマッタが作成されます。format()メソッドは、適切な区切り記号を挿入して数値を文字列に変換します。
ロケール識別子を変更することで、同じ数値を異なるロケール用にフォーマットできます。
const usFormatter = new Intl.NumberFormat('en-US');
console.log(usFormatter.format(1234567));
// Output: "1,234,567"
const deFormatter = new Intl.NumberFormat('de-DE');
console.log(deFormatter.format(1234567));
// Output: "1.234.567"
const frFormatter = new Intl.NumberFormat('fr-FR');
console.log(frFormatter.format(1234567));
// Output: "1 234 567"
各フォーマッターは、そのロケールの規則を適用します。ドイツ語のフォーマッターはピリオドを使用し、フランス語のフォーマッターはスペースを使用し、米国のフォーマッターはカンマを使用します。各ロケールがどの記号を使用するかを知る必要はありません。APIがこれらの詳細を自動的に処理します。
ユーザーのロケールに合わせた数値のフォーマット
特定のロケールをハードコーディングする代わりに、ブラウザからユーザーの優先言語を使用できます。navigator.languageプロパティは、ユーザーの最優先言語設定を返します。
const userLocale = navigator.language;
const formatter = new Intl.NumberFormat(userLocale);
console.log(formatter.format(1234567));
// Output varies by user's locale
// For en-US: "1,234,567"
// For de-DE: "1.234.567"
// For 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));
// Output: "123"
console.log(formatter.format(1234));
// Output: "1,234"
console.log(formatter.format(12345));
// Output: "12,345"
console.log(formatter.format(123456));
// Output: "123,456"
123のような小さな数値には区切り記号は必要なく、区切り記号なしで表示されます。1234以上の数値には、グループ化により可読性が向上するため、区切り記号が付けられます。
APIは、ロケールの規則に基づいて、区切り記号が有益な場合を自動的に判断します。フォーマットする前に各数値の大きさを手動で確認する必要はありません。
桁区切り記号付きの小数のフォーマット
Intl.NumberFormat APIは、数値の整数部分と小数部分の両方を処理します。桁区切り記号は整数部分に表示され、小数点と小数桁はロケールの規則に従います。
const usFormatter = new Intl.NumberFormat('en-US');
console.log(usFormatter.format(1234567.89));
// Output: "1,234,567.89"
const deFormatter = new Intl.NumberFormat('de-DE');
console.log(deFormatter.format(1234567.89));
// Output: "1.234.567,89"
ドイツ語の書式設定では、両方の規則が逆転していることに注意してください。整数部分では桁区切り記号としてピリオドが使用され、小数部分の小数点区切り記号としてカンマが使用されます。Intl APIは、ロケールに基づいて両方の側面を正しく処理します。
非常に大きな数値の処理
数値が大きくなるにつれて、桁区切り記号の重要性が増します。区切り記号がないと、7桁、8桁、または9桁の数値を一目で正確に読み取ることはほぼ不可能です。
const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.format(1234567890));
// Output: "1,234,567,890"
console.log(formatter.format(9876543210));
// Output: "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));
});
// Output:
// "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);
フォーマットされた文字列は、他の文字列値と同様に機能します。テキストコンテンツ、属性、またはユーザーに情報を表示するその他のコンテキストに挿入できます。