とりあえず知っておきたい演算子テクニック(入門編)
フロントエンドでいろいろやっているQと申します。
ニックネームのQはエヴァQではない方のQです。
基本的に業務に関連する記事を書くことになっているのですが、特にそういうのは思いつきませんでした。というわけで今回は、普段の業務では使わないような基礎テクニックをとりとめもなく書いていきたいと思います。
コードの例はJavaScriptを用いていますが、特定の言語のみに限った話ではありませんので、お好きな言語に脳内変換してお読み流し下さい。
ビット演算子
2の累乗の乗除算はビットシフトに置き換えることができます。
1 2 3 4 |
[code lang="javascript"] y = x << 1; // y = x * 2; y = x >> 1; // y = x / 2; [/code] |
また、2の累乗の剰余はビット単位ANDに置き換えることができます。
以下の偶奇判定を行うコードは
1 2 3 |
[code lang="javascript"] y = (x % 2) ? 1 : 0; [/code] |
次のように書くこともできます。
1 2 3 |
[code lang="javascript"] y = (x & 1) ? 1 : 0; [/code] |
これらは昔からある高速化テクニックの一つですが、近年はほとんどの言語・環境では効果が薄いどころか、コンパイラの最適化を阻害する等により逆に遅くなるケースもあるそうなので使用の際は要注意です。
論理演算子
論理演算子が真偽値ではなく一方のオペランドの値を返す場合、if文を置き換えてしまうことが可能です。
ある条件を満たしていたら関数を呼び出す文
1 2 3 |
[code lang="javascript"] if (p) f(); [/code] |
は、論理ANDが左のオペランドが真である場合にのみ右のオペランドを評価する(ショートサーキット評価)規則を利用することで、以下のように表せます。
1 2 3 |
[code lang="javascript"] p && f(); [/code] |
逆に、ある条件が成立しなかった場合に関数を呼び出す文
1 2 3 |
[code lang="javascript"] if (!p) f(); [/code] |
は、論理ORを用いて以下のように表せます。
1 2 3 |
[code lang="javascript"] p || f(); [/code] |
これは遅延初期化のイディオムとして使われることもあります。
以下のような、関数が初めて呼び出された時点で初期化を行うコードは
1 2 3 4 5 6 7 8 |
[code lang="javascript"] function getInstance() { if (!instance) { instance = new Singleton(); } return instance; } [/code] |
一行でまとめて書くことができます。
1 2 3 4 5 |
[code lang="javascript"] function getInstance() { return instance = instance || new Singleton(); } [/code] |
これらは特に処理が早くなるわけではありませんが、うまく使えばコードをシンプルにすることができるので便利です。
カンマ演算子
カンマ演算子は演算子です、ただの区切り文字ではありません。カンマで区切った複数の式を左から順に評価し、最後のオペランドの値を返します。
1 2 3 4 5 |
[code lang="javascript"] for (var i = 0; i < 10; i++) { f(); } [/code] |
は一行で書けます。
1 2 3 |
[code lang="javascript"] for (var i = 0; i < 10; f(), i++); [/code] |
私は個人的にdo-while文があまり好きではありません。ので、
1 2 3 4 5 |
[code lang="javascript"] do { f(); } while (--i); [/code] |
for文に直してしまいます。
1 2 3 |
[code lang="javascript"] for (; f(), --i;); [/code] |
んん?
1 2 3 4 5 6 7 8 |
[code lang="javascript"] if (p) { x = 10; } else { f(); x = 20; } [/code] |
なんか長いですね。一行にしましょう。
1 2 3 |
[code lang="javascript"] x = (p) ? 10 : (f(), 20); [/code] |
もちろんこれらはネタです。が、仕事以外でショートコーディングやトリッキーコードを書きたくなった時に重宝します。自身が普段使っている言語でどんな書き方ができるのか、いろいろ試してみると理解が深まって良いことがあるかもしれません。
おわりに
今回紹介したテクニックは「知ってたわ~2年くらい前から知ってたわ~」と言われそうなものばかりでしたが、応用編ではあっと驚くとんでもないテクニックを紹介する予定です。それでは、私がそのようなテクニックを編み出すであろう数年(数十年)後にまたお会いしましょう!