LoginSignup
15
17

More than 5 years have passed since last update.

if elseif が連続し ||(論理和)が頻出する時はswitchが使えるかも知れない

Last updated at Posted at 2012-12-05

プログラミングをしていると稀によくあるのが次のような if else if が連続する場面。特に || (論理和) が入ってくると何が何やら訳がわからなくなる。

if (A && B || C) {
  //1
} else if (D) {
  //2
} else if (E || F) {
  //3
} else {
  //4
}

論理式の横方向の位置を揃えるのが難しいのでコードの見た目的にも酷いことになりがち。こういう時は switch を使って次のように書ける

switch (true) {
case A && B:
case !!C:
  //1
  break;
case !!D:
  //2
  break;
case !!E:
case !!F:
  //3
  break;
default:
  //4
}

仕組みはいたって簡単で switch(true) なのでラベルが true ならよい。なので C のようBooleanじゃない可能性がある場合 !!C のようにして Boolean に変換してやる必要がある。
いっそのこと全てのラベルを !!(expr) で装飾してしまうのもありか。

これを使えば一見複雑怪奇な if 文もあっさりと理解しやすくなる、、、かも知れないけど、やっぱり普通の無理に一つの論理式にしない方がいいと思う。

if (A && (B || C) || D || (E || (F && G)) || H) {
  //
}

switch(true) {
case !!(A && (B || C)):
case !!D:
case !!(E || (F && G)):
case !!H:
  //
}

a = A && (B || C);
b = E || (F && G);
if (a || D || b || H) {
  // これのほうがよさそう
}

ちなみに、最後のやつは本質的には上の2つと挙動が異なる。それは b に代入するときに E || (F && G) が評価されている点だ。もし a が真なら本来は評価されないはずのものが評価されてしまっている。仮に b がかなり重たい処理を含むとするとパフォーマンスの低下につながらないとはいいきれない。もしくは何かしらの破壊的な変更を含む場合は、最後の方法をとることはできない。

以下は論理的に同じだけど冗長過ぎる気がする

if (A && (B || C)) {
  // 全て
} else if (D) {
  // 同じ
} else if (E || (F && G)) {
  // 処理を
} else if (H) {
  // 行う
}
15
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17