JavascriptでpadLeft

C#で言うところの『padLeft』がほしい、ということで書いてみた。

String.prototype.padLeft = function(len, chr){
  return len < 1 ? this : (function(c){
    var ret = '';
    while (ret.length < len) 
      ret += c;
    return ret;
  })(chr.substr(0, 1) || '0') + this;
}

alert("1".padLeft(4, "0")); //0001

しかし、何か気に入らないのでWebで調べると、どうもprototype.jsで同じような関数があることが分かった。
必要なのは『times』関数。で、それに少々手を加えてみる。
この中身を見ると、自身の文字列の長さを無視しているので、このままだと埋める文字の長さが一文字以上だとおかしな結果になるので『this.substr(0, 1) || ''』とした。まあ余計な対応かもしれないが不必要なら削除すれば良い。


以下が最終的な形。
String.prototype.times = function(len){
  return len < 1 ? '' : new Array(++len).join(this.substr(0, 1) || '');
}

String.prototype.padRight = function(len, chr){
  return this + chr.times(len - this.length);
}

String.prototype.padLeft = function(len, chr){
  return chr.times(len - this.length) + this;
}
処理速度的には私が書いたものとほとんど変わらないが、コードはすっきりしているのでこちらの方が良いだろう。


padRightが必要ないならtimesを分けて書く必要がないので、下記のように併せてしまえばもっと処理は速くなる。
String.prototype.padLeft = function(len, chr){
  return len < 1 ? this : new Array(++len - this.length).join(chr.substr(0, 1) || '') + this;
}

2進数、10進数、16進数の相互変換

Javascriptで2進数、10進数、16進数の相互変換を行う。

10進数が絡むと簡単なのだが、2進数から16進数やまたその反対への変換には一旦10進数を経由する必要がある。
もっと良くならないかといろいろ試し、自分で処理を書いてみたりしたが、結局素直に下記のようにするのが処理速度的にも一番速かった。

var foo;

//16進数→2進数
foo = parseInt("a", 16).toString(2); //1010

//16進数→10進数
foo = parseInt("a", 16); //10

//10進数→2進数
foo = (10).toString(2); //1010
foo = 0xA.toString(2); //1010

//10進数→16進数
foo = (10).toString(16); //a

//2進数→10進数
foo = parseInt("1010",2); //10

//2進数→16進数
foo = parseInt("1010",2).toString(16); //a

因みに16進数のリテラルは内部的には10進数に置き換えられちゃうようですね。要するに変換の必要なしで型は『Number』になり、例えば『0xA』を参照すると『10』が返ってきます。16進数を扱うときは大概文字列で扱ってたので知りませんでした。



参考

参考までに16進数から2進数に変換する処理を載せておきますが、ボツネタなんで適当にスルーして下さい。

単純に16進数の一文字を2進数に変換するだけなら以下のようにすれば良い。
String.prototype.hexToBin = function(){
  return {
    "0": "0000",
    "1": "0001",
    "2": "0010",
    "3": "0011",
    "4": "0100",
    "5": "0101",
    "6": "0110",
    "7": "0111",
    "8": "1000",
    "9": "1001",
    "A": "1010",
    "B": "1011",
    "C": "1100",
    "D": "1101",
    "E": "1110",
    "F": "1111"
  }[this.toUpperCase()] || "";
}

alert("F".hexToBin()); //1111

しかし、符号やプレフィックス("0x")の有無、そして小数点を考慮すると以下のような処理が必要になる。
String.prototype.hexToBinary = function(){
  var
  sep = this.match(/^-/) ? "-" : "",
  hxs = this.replace(/(-|0x)/g,"").split("."),
  ret = [], tmp, hx;

  for (var i = 0; i < hxs.length; i++) {
    tmp = "";
    hx = hxs[i];

    for (var k = 0; k < hx.length; k++) 
      tmp += hx.charAt(k).hexToBin();

    ret.push(tmp);
  }
  
  return sep + ret.join(".");
}

alert("-0xF.A7".hexToBinary()); //-1111.10100111

処理速度的に上に書いたシンプルなものには及ばないのでボツとなりました。

Sony Style(ソニースタイル)
デル株式会社

Recent Posts