Panda Noir

JavaScript の限界を究めるブログです。

文字列をかけ算する関数、ある文字を数える関数

作ったのですが、すてるのもったいないのでメモしておきます。 ここでいう「文字列の掛け算」とは、 めちゃ×2イケてるっ に見られるような文字列を任意の回数繰り返す演算のことです(ちょっとオカタク説明してみました)。

文字列を任意の回数くりかえす関数

function mult(b, c) {for(var a = “”; 0 < c;) a += b, c–;return a}

function count(b, c) {for(var a = cnt = 0, d = b.length; a < d; a++) b.charAt(a) == c && cnt++;return cnt};

function mult(str, n) {
    for(var res = ""; n > 0; res += str, n--);
    return res;
}
function mult2(str, n){
    return Array(n + 1).join(str);
}
function mult3(str, n){
    return n <= 0 ? '' :mult3(str + str, 0 | n / 2) + (n % 2 === 0 ? '' : str);
}

上から順にオーソドックスな実装、空の配列をつなげるという少々トリッキーな実装、再帰による計算量を落とし込んだ実装、となっています。

個人的に一番初めの関数がfor文のなかに全て詰め込めてすっきりさせることができたので満足しています。他にもmult3をforに落とし込んだもの、ネイティヴのメソッド(String.prototype.repeat())によるもの、などいろいろあります(私は思いついてません)。ちなみにString.prototype.repeat()は 2015年7月27日 現在ほとんどのブラウザがサポートしておらず実験的なものとなっています。実用ではまだまだとても採用できそうにないです。

速度面では mult()が最速、mult3()が2番目、mult2()が最も遅かったです。

ちなみに上の関数は n にマイナスが入れられる、strに文字列以外が渡されるなどすると意図しない動作をします。まあ実用で上記のコードは使わないでしょうが一応。

ある1文字が何回現れるか数える関数

function count(str, s) {
    for(var i = 0, _i = str.length, res = 0; i < _i; str.charAt(i) === s && (res = 0 | res + 1), i = 0 | i + 1);
    return res;
}
function count2(str, s) {
    for (var pos = str.indexOf(s), res = 0; pos !== -1; pos = str.indexOf(s, pos + 1), res = 0 | res + 1);
    return res;
}

これもまたfor文のみで完結しています。なかなかの逸品だとおもいます。res = 0 | res + 1 が カッコで囲われているのは、 && の方が = よりも優先順位が高く、 (str.charAt(i) === s && res) = 0 | res + 1と評価されてしまうからです。まあ普通 a = b && cとなっているわけで = が優先順位低くて当たり前なのですが、ちょっと敗北感が残って残念です。

ちなみに速度面では count() より count2() の方がはるかに速い模様です。

終わりに

今回のfor文あたりの圧縮テクニックなど意外と初見だとわけがわからない手法ばんばん使ってみました。演算子ノ全テという記事でどうしてこんなコードが動くのかだいたい説明したのでよろしければ ご覧ください。