数値をカンマ区切りにする2007年12月07日 00時10分

JavaScript で数値を 3 桁ごとにカンマで区切るお話。「comma separation by javascript - さらさら宇宙忍法帖」にいろいろまとまっている。

ここでの基本的な方針としては 1 回の文字列置換で終わらせること。元のコードは Perlメモの「数字を 3桁ごとにコンマで区切る」。でも小数への対応を考えると 1 回では無理っぽかったので、小数点が含まれる場合は文字列を分割して処理することに。というわけでいきなり結論。

Number.prototype.toDeliminated = function () {
  var string = "" + +this;
  var pointIndex = string.indexOf(".");
  return (pointIndex == -1)
         ? string.replace(/(\d{1,3})(?=(?:\d\d\d)+$)/g, "$1,")
         : string.substring(0, pointIndex)
                 .replace(/(\d{1,3})(?=(?:\d\d\d)+$)/g, "$1,") +
           string.substring(pointIndex)
                 .replace(/(\d\d\d)(?=\d)/g, "$1,");
};

(-1234.56789).toDeliminated(); // => -1,234.567,89

さらさら宇宙忍法帖の実験コードで試した限りでは、整数に関しては「iandeth. - javascriptで数値をカンマ区切り文字列に変換する関数メモ」よりほんの少し速く、小数に関してはそれよりだいぶ遅いみたい。小数部にカンマを入れる処理をなくせば差はかなり迫ってくるけど。

Number.prototype.toCommaed2 - ’ellaneous」より。確かに小数点が入ってると仮定すれば 1 回の置換でいけますね。

Number.prototype.toDeliminated = function () {
  var string = "" + +this;
  return string.replace((string.indexOf(".") == -1)
                        ? /(\d{1,3}(?=(?:\d\d\d)+$))/g
                        : /(\d{1,3}(?=(?:\d\d\d)+\.)|\d\d\d(?=\d+$))/g,
                        "$1,");
};

しかし速度はそんなに変わらない。というよりむしろ遅くなってる。失敗時のコストが跳ね上がるからか。