かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript 数字のゼロ埋め(ゼロパディング)・少数の桁あわせがしたい

Viewで表示する時に桁揃えたいとかありがちなやつで、やり方結構忘れるからメモ

ゼロパディング

001234 こんなやつ

先頭に 0 を足して slice する方法

伝統的な感じの方法。

const zeroPadding = (num) => (digits = 2) => {
  if (num.toString().length > digits) {
    return num.toString();
  }
  const prefix = '0'.repeat( digits );
  return `${prefix}${num}`.slice( -digits );
};

zeroPadding(3)(2)   // => "03"
zeroPadding(10)(2)  // => "10"
zeroPadding(100)(2) // => "100"

String.prototype.padStart() を使う方法

ES2017 で定義されたらしい。
殆どのモダンブラウザではもう使えるっぽい。 (知らなかった…
https://caniuse.com/#search=padStart

padStart() メソッドは、結果の文字列が指定した長さになるように、現在の文字列を他の文字列で (必要に応じて繰り返して) 延長します。延長は、現在の文字列の先頭から適用されます。
cf. String.prototype.padStart() - JavaScript | MDN

const zeroPadding = (num) => (digits = 2) => {
  return num.toString().padStart(digits, 0);
};

zeroPadding(3)(2)   // => "03"
zeroPadding(10)(2)  // => "10"
zeroPadding(100)(2) // => "100"

フォーマットしている桁数を越していると、元の数字のまま返してくれる。

小数の桁あわせ ( 小数点以下n桁で四捨五入したい )

独自実装してみる

欲しい小数点以下の桁数まで整数にして、 Math.round() で四捨五入して元の桁に戻せばOK

const formatToDecimalPlaceDigits = (num) => (digits = 2) => {
  if (Number.isFinite(digits) === false || digits < 1) {
    return Math.round(num);
  }
  const decimalDigits = 10 ** Math.floor(digits);
  return Math.round( Number.parseFloat(num) * decimalDigits ) / decimalDigits;
};

var n = 1.41421356;

formatToDecimalPlaceDigits(n)(2)  // => 1.41
formatToDecimalPlaceDigits(n)(6)  // => 1.414214
formatToDecimalPlaceDigits(5.1)(2)  // => 5.1
formatToDecimalPlaceDigits(5.1)(-1) // => 5
formatToDecimalPlaceDigits(-1.235)(2) // => -1.24
formatToDecimalPlaceDigits('3.14')(1) // => 3.1
formatToDecimalPlaceDigits(false)(1)  // => NaN

この方法は数値を返しているので、1.00 みたいに桁数を揃えて表示したい場合には不向きです。
View で小数点以下の数値の桁数を揃えて表示したい場合は文字列にして桁数をあわせる方法にする必要があります。

Number.prototype.toFixed() で小数点以下の桁数を合わせる

Number.prototype.toFixed() は小数点以下の桁数を合わせた文字列を返してくれます。
cf. Number.prototype.toFixed() - JavaScript | MDN

const formatToDecimalPlaceDiditsString = (num) => (digits = 2) => {
  return Number.parseFloat(num).toFixed(digits);
};

formatToDecimalPlaceDiditsString(n)(2)  // => "1.41"
formatToDecimalPlaceDiditsString(n)(6)  // => "1.414214"
formatToDecimalPlaceDiditsString(5.1)(2)  // => "5.10"
// formatToDecimalPlaceDiditsString(5.1)(-1)
// => RangeError: toFixed() digits argument must be between 0 and 100
formatToDecimalPlaceDiditsString(-1.235)(2) // => "-1.24"
formatToDecimalPlaceDiditsString('3.14')(1) // => "3.1"
formatToDecimalPlaceDiditsString(false)(1)  // => "NaN"

View で桁数を合わせて表示したいような場合は、.toFixed() を使うのが簡単で良さそうです!
数値で得たい場合も Number.parseFloat( num.toFixed(digits) ) するで良さそう。 (独自実装の必要なかった… toFixed() は引数によってはエラーになるようなので、あまりないとは思うけど注意が必要です。

RangeError
digits が小さ過ぎたり大き過ぎた場合。0 以上 20 以下の値は RangeError を起こさないでしょう。実装によっては、より大きい、あるいは、小さい値がサポートされているかも
Number.prototype.toFixed() - JavaScript | MDN

感想

JavaScript どんどん新しい機能が追加されてて、昔は色々独自実装してたけど便利なメソッドが追加されて独自実装の必要が無くなってる事が結構ある感じ。(その昔は trim メソッドを実装されないブラウザ用に String.prorptype.trim で実装したりしていたのじゃよ。。。。)
独自実装する前に調べてみるのが良さそうですね。独自実装してみることで考える力がつくってのはあると思ってますが。


[参考]

詰み本…