この記事は第2のドワンゴ Advent Calendar 2018 18日目の記事です。
ドワンゴでニコニコ生放送のWebフロントエンジニアをやっています、 @misuken です。
まだ空きがあったので 14日目の React + TypeScript における ViewComponent の美しい合成技術 に続いての投稿します。
今回はニコニコ生放送でも使用されている、超簡単に数値を 1,234 1.2万 12.3万 123万 1,234万 1.23億 ... に整形する方法を紹介します。
処理
早速ですが超簡単なコードがこちらです。
function format(n, patterns) {
const s = String(Math.abs(n));
const pattern = patterns[(n < 0 ? "-" : "") + s.length] || (patterns[s.length] && `-${patterns[s.length]}`);
return `${pattern ? pattern.replace(s.length < 10 ? /\d/g : /\d\d/g, pos => s[s.length - pos]): n}`;
}
整形パターン
使用するときは桁数に合わせて桁番号を記述したパターンを用意します。
const patterns = {
1: "1",
// 2桁の数値の 2桁目の数 + 1桁目の数 という意味になります
2: "21",
// 3桁の数値の 3桁目の数 + 2桁目の数 + 1桁目の数 という意味になります
3: "321",
4: "4,321",
5: "5.4万",
6: "65.4万",
7: "765万",
8: "8,765万",
9: "9.87億",
// 10桁目からは2桁で指定します
10: "1009.08億",
11: "111009億",
12: "12,111009億",
13: "13.1211兆",
14: "1413.12兆",
15: "151413兆",
// 負の値も対応できますが省略しても機能します。
// 省略時は正のフォーマットの頭に "-" が付いたものを使用します。
"-2": "-21",
// 好きな形式で自由に指定できます
"-15": "マイナス151413兆12,111009億",
};
結果
実際に呼び出してみるとこうなります。
format(0, patterns); // 0
format(1, patterns); // 1
format(12, patterns); // 12
format(123, patterns); // 123
format(1234, patterns); // 1,234
format(12345, patterns); // 1.2万
format(123456, patterns); // 12.3万
format(1234567, patterns); // 123万
format(12345678, patterns); // 1,234万
format(123456789, patterns); // 1.23億
format(1234567890, patterns); // 12.3億
format(12345678901, patterns); // 123億
format(123456789012, patterns); // 1,234億
format(1234567890123, patterns); // 1.23兆
format(12345678901234, patterns); // 12.3兆
format(123456789012345, patterns); // 123兆
format(-12345678901234, patterns); // -12.3兆
format(-123456789012345, patterns); // マイナス123兆4,567億
// フォーマットが定義されていない桁数を指定すると文字列化されて返されます
format(-1234567890123456, patterns); // -1234567890123456
超簡単 ♪( ´θ`)ノ
解説
function format(n, patterns) {
// 数値を整数の文字列にする
const s = String(Math.abs(n));
// 桁数に合わせてパターンを決定します(負の桁数のパターンが無い場合は、正の桁数のパターンを加工)
const pattern = patterns[(n < 0 ? "-" : "") + s.length] || (patterns[s.length] && `-${patterns[s.length]}`);
// パターン文字列の数字を正規表現でマッチさせて、
// マッチした数字が指示する右からpos桁目の数字に置換します。
// "1234"[2] で "3" を取得できる言語仕様と、10桁目から正規表現を切り替えるところがミソです。
return `${pattern ? pattern.replace(s.length < 10 ? /\d/g : /\d\d/g, pos => s[s.length - pos]): n}`;
}
まとめ
数値の桁数と、パターンに記述された対応する桁番号を上手に利用すると、超簡単な処理で自由度の高いフォーマットを実現できます。