gotin blog

Whatever gotin wanna write

comma separation by javascript

suVeneのあれ: [JavaScript]数値を3桁ごとに区切る

これ↑を見かけたので試してみました。
最初に結論を書いておくと、やっぱり

iandeth. - javascriptで数値をカンマ区切り文字列に変換する関数メモ

↑これ速いですね。
僕が考えたものも載せてありますが、速くしようと努力した訳じゃなくて、
こうやれば動くかなぁ、あ、動いた、よかったよかった、ってだけのものですので、
あしからず。

追記5

2007-12-07 - ellaneous

数値をカンマ区切りにする: Days on the Moon

を追加。
gotin版もちょっと修正(でも速度はむしろ低下。。)

追記4

Sbox Error

↑こちらは修正版にしました(小数点対応化されました)
また、検証用のマシンを変えたので結果も全体的に早くなってます。

追記3

Sbox Error

↑こちらにも同様の取り組みを発見したのでテスト対象に追加させてもらいました。

追記2

この計測の仕方よくないかも。ばらつきが大きいや。
なので今ここに載っている計測結果も信憑性は低いです。すみません。

追記

あ、gotin版-を考慮してないや。失格。
修正。

3桁ごとに区切る - Higé au lait
Number.prototype.split3_1 = function() {
    var r = "";
    var s = this.toString().split("").reverse();
    for(var i = 0; i < s.length; i++) {
        if(i % 3 == 0 && i != 0 && s[i] != "-") {
            r = s[i] + "," + r
        } else {
            r = s[i] + r;
        }
    }
    return r;
}
iandeth. - javascriptで数値をカンマ区切り文字列に変換する関数メモ
Number.prototype.split3_2 = function () {
    var to = String(this);
    var tmp = "";
    while (to != (tmp = to.replace(/^([+-]?\d+)(\d\d\d)/,"$1,$2"))){
        to = tmp;
    }
    return to;
}
JavaScriptで数値を3桁ごとに区切る - 0xFF
Number.prototype.split3_3 = function() {
        var m = (this < 0) ? -1 : 1;
        var str = String(this*m).split('.');
        var arr = String(str[0]).split(''), len = Math.ceil(arr.length/3), res = [];
        for (var i =0;i<len;++i) res.push(arr.splice(-3,3).join(''));
        return (m == -1 ? '-' : '') + res.reverse().join(',') + (str[1] ? '.' + str[1] : '');
};
suVeneのあれ: [JavaScript]数値を3桁ごとに区切る
Number.prototype.split3_4 = function() {
  ('' + this).match(/(-?)([0-9]+)(\.[0-9]*)?/);
  var sp = [RegExp.$1, RegExp.$2, RegExp.$3];
  var x = Math.floor(sp[1].length / 3) * 3;
  var len = sp[1].length;
  return sp[0] + (sp[1].substr(0, len - x)) + (len - x == 0 ? '' : ',') +
         (sp[1].substr(len - x, x).match(/[0-9]{3}/g).join(',')) + sp[2];
}
Sbox Error
Number.prototype.split3_5 = function() {
  var r = '', s = this.toString();
  s.match(/(-?)([0-9]+)(\.[0-9]*)?/);
  var sp = [RegExp.$1, s = parseInt(RegExp.$2), RegExp.$3];
  while(s >= 1000) {
    r = ',' + (s%1000) + r;
    s = parseInt(s/1000);
  }
  return sp[0] + s + r + sp[2];
}
2007-12-07 - ellaneous
Number.prototype.split3_6 = function(interval){ var i = interval | 0 || 3;
  return (this + (this == parseInt(this) ? '.' : '#')).replace(
    RegExp('(\\d+?)(?=(?:\\d{'+i+'})+\\.)|(\\d{'+i+'})(?=\\d+#)', 'g'),
    '$1$2,').slice(0, -1);
};
数値をカンマ区切りにする: Days on the Moon
Number.prototype.split3_7 = 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,");
};


gotin版(中身はほとんど変えず、ちょっとだけ短くした)

Number.prototype.split3_g = function(){
    (""+this).match(/([-+]?)(\d*)(\.\d*)?/);
  for(var buf=[],tmp=Math.floor(parseInt(RegExp.$2));tmp > 0;tmp = Math.floor(tmp/ 1000)){
    buf.unshift(tmp%1000);
  }
  return RegExp.$1 + buf.join(",") + RegExp.$3;
};

実験

// print definition.
// use console.log() when "this" has Firebug.
// Usually I use spidermonkey for tests like this script.
if("console" in this){
  function print(m){
    console.log(m);
  }
}

// test number
var x = 123456789;
var x2 = -123456789.123456789876;

// timer(1000times test)
function time(f){
  var s = new Date().getTime();
  for(var i=0;i<1000;i++)
    f.apply(x);
  return new Date().getTime()-s;
}

Array.prototype.each = function(f){
  for(var i=0,l=this.length;i<l;i++){
    f(this[i], i);
  }
};

// experiments
with(Number.prototype){
  var splits = "split3_1 split3_2 split3_3 split3_4 split3_5 split3_6 split3_7 split3_g".split(" ");

  print("// result:" + x);
  splits.each(function(f,i){print(splits[i]+":"+eval(f).call(x))});
  print("");
  print("// result:" + x2);
  splits.each(function(f,i){print(splits[i]+":"+eval(f).call(x2))});
  print("");
  print("// time:" + x);
  splits.each(function(f,i){print(splits[i]+":"+time(function(){eval(f).call(x)}))});
  print("");
  print("// time:" + x2);
  splits.each(function(f,i){print(splits[i]+":"+time(function(){eval(f).call(x2)}))});
  print("");
}

結果

// result:123456789
split3_1:123,456,789
split3_2:123,456,789
split3_3:123,456,789
split3_4:123,456,789
split3_5:123,456,789
split3_6:123,456,789
split3_7:123,456,789
split3_g:123,456,789

// result:-123456789.12345679
split3_1:-123,456,789,.12,345,679  //?
split3_2:-123,456,789.12345679
split3_3:-123,456,789.12345679
split3_4:-123,456,789.12345679
split3_5:-123,456,789.12345679
split3_6:-123,456,789.123,456,79   //?
split3_7:-123,456,789.123,456,79   //?
split3_g:-123,456,789.12345679

// time:123456789
split3_1:53
split3_2:41
split3_3:84
split3_4:60
split3_5:48
split3_6:54
split3_7:37 // fastest!
split3_g:61

// time:-123456789.12345679
split3_1:74
split3_2:45 // fastest!
split3_3:90
split3_4:66
split3_5:52
split3_6:76
split3_7:52
split3_g:56


*/