読者です 読者をやめる 読者になる 読者になる

console.lealog();

@leader22のWeb系に関する勉強めもブログですのだ

15桁以上のIDとかをマイナス1する関数

そんな関数いつ使うんやって話でしょうが、いる時はいるんです・・w

TwitterAPIとか使うと、ツイートIDを取り回す必要があったりします。
具体的には現在表示されてるツイートより古いものを・・って場合に必要です。

で、さすがのTwitterさまとなると、IDの桁も馬鹿にならんわけで。

単純にマイナス1すると

document.write(10000000000000000);
document.write(10000000000000000 - 1); // 10000000000000000・・だと・・?!

減らない!何これ!
詳しくは知りませんが、有効桁数が決まってるみたいですね。
で、そんなデカすぎる数値のことは知らん、と。

参考:JavaScript 型の解説 - Wikibooks

なので、こうなったら文字列としてごにょごにょするしかない・・と。

文字列としてマイナス1する関数

というわけで、書きました。

// 引数にはマイナス1したい数値を。
// おそらくこんな関数が必要な場合は20桁くらいになってるはずなので文字列を想定。
var minus1 = function(strNumber) {
  // [A]1ー9の値と末尾:末尾が0ではなくて、1桁のみ-1すればOKのパターン
  // [B]0以外の数値の後に0が1回以上繰り返して末尾:n0とかn00とかn000とか、(n-1)999ってしたいパターン
  var reg = /(([1-9])0+)$|([1-9])$/,
    ex = reg.exec(strNumber);

  if (ex && RegExp.$2) {
    // [B]の場合
    // n0とかn00のnを取得して、-1
    var regFirstDigit = parseInt(RegExp.$2, 10) - 1;
    if(regFirstDigit === 0){ regFirstDigit = ''};
    // 全体の桁数から先頭を引いた分、9をつなげたものを作成
    var i = 0, l = RegExp.$1.length - 1;
    var regOtherDigit = '';
    for (; i < l; i++) {
      regOtherDigit += '9';
    }
    // つなげてリターン
    return RegExp.leftContext + regFirstDigit + regOtherDigit;
  } else if (ex) {
    // [A]の場合
    // マッチした値を素直に−1
    var regFirstDigit = parseInt(ex, 10) - 1;
    // つなげてリターン
    return RegExp.leftContext + regFirstDigit;
  } else {
    // 考えられないけど一応マッチしなかった時用
    return strNumber;
  }
};

minus1('123456789'); // 123456788
minus1('209328741298743'); // 209328741298742
minus1('1000000000000000000000'); // 999999999999999999999

最初は全部配列にsplitして、それで・・とか考えてたんですけど、文字列操作ならもうどストレートにやろうと。
引数はTwitterAPIの検索APIだと、id_strとかを想定してます。

まぁただマイナス1するだけですが、何桁のが来ても大丈夫なはず・・。

やっててよかった正規表現