パーセント記号を使用したパーセンテージのフォーマット方法
Intl.NumberFormatのパーセントスタイルを使用して、ロケールに適したフォーマットでパーセンテージとして数値を表示する
はじめに
パーセンテージは、完了進捗の表示から金利や割引額の表示まで、多くのアプリケーションで使用されます。数値にパーセント記号を連結するシンプルなアプローチは基本的なケースでは機能しますが、異なる言語や地域でのパーセンテージのフォーマット方法を考慮できません。トルコ語では、パーセント記号は%50のように数値の前に表示されます。フランス語では、50 %のように数値とパーセント記号の間にスペースが入ります。アラビア語では、標準の%記号の代わりに特別なパーセント文字を使用します。
JavaScriptのIntl.NumberFormat APIは、これらのフォーマットの違いを自動的に処理します。styleオプションを"percent"に設定することで、ロケール固有のコードを記述することなく、任意のロケールに対して正しくフォーマットされたパーセンテージを取得できます。
パーセンテージのフォーマットがロケールによって異なる理由
パーセント記号の位置とスペースのルールは、ロケールによって異なります。英語では、パーセント記号はスペースなしで数値の直後に配置されます。フランス語では、パーセント記号の前にスペースが追加されます。トルコ語では、パーセント記号は数値の前に配置されます。これらの違いは、各言語の自然な読み方と慣習を反映しています。
フォーマットの違いは、記号の配置だけにとどまりません。一部のロケールでは、パーセント記号に異なる文字を使用します。アラビア語では、ASCII パーセント記号の代わりに٪(U+066A)を使用します。小数点区切り文字と桁区切り文字も、通常の数値フォーマットと同様に、ロケールによって異なります。
文字列連結でパーセンテージのフォーマットをハードコーディングすると、すべてのユーザーに単一のロケールのフォーマットを強制することになります。フランス語のユーザーが50 %ではなく50%を見ると、不自然なフォーマットを経験します。トルコ語のユーザーが%50を期待しているのに50%を見ると、同じ問題に直面します。Intl APIは、各ロケールに正しいフォーマットルールを適用することで、この問題を解決します。
パーセンテージとしての数値のフォーマット
Intl.NumberFormatのstyleオプションは、数値を通常の数値、通貨、パーセンテージ、または単位としてフォーマットするかを制御します。数値をパーセンテージとしてフォーマットするには、styleを"percent"に設定します。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(0.75));
// Output: "75%"
console.log(formatter.format(0.05));
// Output: "5%"
console.log(formatter.format(1.5));
// Output: "150%"
フォーマッターは入力値を自動的に100倍し、パーセント記号を追加します。つまり、フォーマッターには小数値を渡します。0.75の値は75%になります。1.5の値は150%になります。
この小数入力の規則は、数学やほとんどのプログラミング計算におけるパーセンテージの動作と一致しています。成長率や完了率などのパーセンテージを計算する場合、結果は通常0から1の間の小数値になります。この値を最初にパーセンテージに変換することなく、フォーマッターに直接渡すことができます。
小数入力値の理解
パーセンテージフォーマッターは、1.0が100%を表す小数入力を想定しています。この設計上の選択は、コードでパーセンテージがどのように計算されるかと一致しています。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
// Calculating completion percentage
const completed = 75;
const total = 100;
const ratio = completed / total;
console.log(formatter.format(ratio));
// Output: "75%"
// Calculating growth rate
const oldValue = 1000;
const newValue = 1250;
const growth = (newValue - oldValue) / oldValue;
console.log(formatter.format(growth));
// Output: "25%"
completedをtotalで割ると、0.75が得られます。これをフォーマッターに直接渡すと、75%として表示されます。変化量を元の値の比率として成長率を計算すると、0.25が得られます。フォーマッターはこれを25%として表示します。
このアプローチにより、開発者がフォーマット前に100を掛けてしまい、75%ではなく7500%のような値になってしまうという一般的なエラーを防ぎます。フォーマッターが乗算を処理するため、コード内では自然な小数表現で作業できます。
0-1の範囲外の値の処理
パーセンテージは0%から100%の間の値に限定されません。ゼロ未満の値は負のパーセンテージを表します。1.0を超える値は100%を超えるパーセンテージを表します。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(-0.15));
// Output: "-15%"
console.log(formatter.format(2.5));
// Output: "250%"
console.log(formatter.format(0.0025));
// Output: "0%"
負の値はマイナス記号付きで表示されます。これは減少、損失、またはマイナス成長率を表示する際に便利です。1.0より大きい値は100%を超えるパーセンテージとして表示され、前年比成長率や新しい値がベースラインを超える比較を表示する際に一般的です。
非常に小さい値は、デフォルトの精度設定により0%に丸められる場合があります。0.25%を表す0.0025という値は、パーセンテージのデフォルト最大小数桁数が0であるため、0%と表示されます。次のレッスンでは、これらの小さなパーセンテージを正確に表示するために小数点以下の桁数を制御する方法について説明します。
異なるロケールでのパーセンテージの書式設定
パーセンテージの書式設定は、指定したロケールに適応します。各ロケールは、記号の配置、スペース、および記号に独自のルールを適用します。
const enFormatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(enFormatter.format(0.5));
// Output: "50%"
const frFormatter = new Intl.NumberFormat("fr-FR", {
style: "percent"
});
console.log(frFormatter.format(0.5));
// Output: "50 %"
const trFormatter = new Intl.NumberFormat("tr-TR", {
style: "percent"
});
console.log(trFormatter.format(0.5));
// Output: "%50"
const arFormatter = new Intl.NumberFormat("ar-SA", {
style: "percent"
});
console.log(arFormatter.format(0.5));
// Output: "٪50"
英語ではパーセント記号を数値の直後に配置します。フランス語ではパーセント記号の前にスペースを追加します。トルコ語ではパーセント記号を数値の前に配置します。アラビア語ではアラビア語のパーセント記号を使用し、右から左へのテキスト方向に従います。
これらの違いは、ロケールパラメータに基づいて自動的に発生します。異なるロケールを処理するための条件付きロジックを記述する必要はありません。ユーザーのロケールでフォーマッタを作成すると、そのロケールに適した出力が生成されます。
パーセンテージの小数点以下の桁数の制御
デフォルトでは、パーセンテージの書式設定は小数点以下を表示しません。0.755のような値は、四捨五入後に76%として表示されます。minimumFractionDigitsおよびmaximumFractionDigitsオプションを使用して、小数点以下の桁数を制御できます。
const defaultFormatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(defaultFormatter.format(0.755));
// Output: "76%"
const oneDecimalFormatter = new Intl.NumberFormat("en-US", {
style: "percent",
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
console.log(oneDecimalFormatter.format(0.755));
// Output: "75.5%"
const twoDecimalFormatter = new Intl.NumberFormat("en-US", {
style: "percent",
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(twoDecimalFormatter.format(0.755));
// Output: "75.50%"
minimumFractionDigitsオプションは、フォーマッタが少なくともその桁数の小数点以下を表示することを保証し、必要に応じて末尾にゼロを追加します。maximumFractionDigitsオプションは、小数点以下の桁数を制限し、必要に応じて値を四捨五入します。
両方を同じ値に設定することで、すべてのパーセンテージで一貫した書式設定が保証されます。これは、すべてのパーセンテージを視覚的に揃えたい表やグラフで便利です。
次のレッスンでは、小数点以下の桁数制御について、末尾のゼロの処理方法や非常に小さなパーセンテージを正確に表示する方法を含めて、より詳しく説明します。
パーセンテージと符号表示の組み合わせ
パーセンテージの書式設定はsignDisplayオプションと組み合わせて、正のパーセンテージにプラス記号を明示的に表示できます。これは、符号が方向を示す変化率や成長率を表示する際に便利です。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent",
signDisplay: "always",
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
console.log(formatter.format(0.0523));
// Output: "+5.2%"
console.log(formatter.format(-0.0341));
// Output: "-3.4%"
console.log(formatter.format(0));
// Output: "+0.0%"
signDisplayオプションは以前のレッスンで説明しました。パーセンテージの書式設定と組み合わせると、パーセンテージが増加を表すのか減少を表すのかが明確になります。明示的なプラス記号がない場合、利益と損失の両方が表示される文脈では、正のパーセンテージが曖昧になる可能性があります。
ゼロをパーセンテージとして書式設定する
ゼロはデフォルトで0%として書式設定されます。ゼロの処理方法は、ゼロが変化なし、値なし、または意味のある測定値のいずれを表すかによって異なります。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(0));
// Output: "0%"
const withSignFormatter = new Intl.NumberFormat("en-US", {
style: "percent",
signDisplay: "exceptZero"
});
console.log(withSignFormatter.format(0.05));
// Output: "+5%"
console.log(withSignFormatter.format(0));
// Output: "0%"
signDisplay: "exceptZero"を使用すると、正と負のパーセンテージには符号が表示されますが、ゼロの符号は省略されます。これにより、ゼロが変化なしのような中立的な状態を表す場合に、視覚的に区別されます。
パーセンテージ書式設定を使用する場合
パーセンテージ書式設定は、パーセンテージとして自然に表現される比率、率、または割合を表示する際に使用します。一般的な使用例には、完了進捗、金利、割引額、成長率、成功率、確率値などがあります。
ロケールに関係なく、パーセント記号を特定の位置に表示する必要がある場合は、パーセンテージ書式設定を使用しないでください。デザイン上、視覚的な一貫性のためにパーセント記号を常に右側に表示する必要がある場合は、代わりに文字列連結を使用してください。ただし、これは国際化の正確性を犠牲にします。
また、すでに100倍されている値を扱う場合は、パーセンテージ形式を使用しないでください。データが75を75%として保存している場合は、フォーマット前に100で割るか、パーセント記号を手動で追加したプレーンな数値フォーマットを使用してください。
パーセンテージフォーマッターの精度について
パーセンテージフォーマットのデフォルト精度は小数点以下0桁です。これは、入力値に基づいて精度を調整するプレーンな数値フォーマットとは異なります。パーセンテージフォーマッターは、小数桁オプションを明示的に設定しない限り、値を整数パーセンテージに丸めます。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(0.755));
// Output: "76%"
console.log(formatter.format(0.754));
// Output: "75%"
console.log(formatter.format(0.001));
// Output: "0%"
値は最も近い整数パーセンテージに丸められます。0.755は76%に丸められます。0.754は75%に丸められます。0.001のような非常に小さい値は0%に丸められます。
小さなパーセンテージや小数点以下のパーセンテージを表示する必要がある場合は、最大小数桁数を増やしてください。次のレッスンでは、精度制御について詳しく説明します。