【JavaScriptクイズ】第2問:if文を減らすには
JavaScriptの文法や便利な使い方について、気軽なクイズ形式で解説する記事を書いていきます。
今回のテーマは「if文の整理」です。では、さっそく問題です!
問題
JavaScriptを使って、次のような形式のオブジェクトで「長さ」を表すものとします。
// これは「150ミリメートル」を表す
{
unit: "mm",
value: 150
};
{ // これは「150センチメートル」を表す
unit: "cm",
value: 150
};
このとき、「長さが1メートルを超えるか」を判定する関数isGreaterThan1Meter
を作りました。
"use strict";
function isGreaterThan1Meter(length) {
if (length.unit === "mm") {
if (length.value > 1000) {
return true;
}
}
if (length.unit === "cm") {
if (length.value > 100) {
return true;
}
}
return false;
}
let length1 = { // 150ミリメートル
unit: "mm",
value: 150
};
console.log("length1: " + isGreaterThan1Meter(length1));
let length2 = { // 150センチメートル
unit: "cm",
value: 150
};
console.log("length2: " + isGreaterThan1Meter(length2));
このプログラムを実行すると、以下のような出力を得られます。
length1: false
length2: true
-
length1
は150ミリメートルで、1メートルより大きくないのでfalse
-
length2
は150センチメートルで、1メートルより大きいのでtrue
という結果です。
さて、関数の内側にはif
文が4つ見えると思います。実行結果が変わらないように気を付けながら、if
文の数をできるだけ減らしてください。いくつまで減らせますか?
ヒントを見る?
まずは「AND条件(&&
)」を使って、if
のネスト(入れ子)を減らしてみましょう。
答えを見る?
次のようにすれば、if
文は1つもなくなります。
"use strict";
function isGreaterThan1Meter(length) {
return (
((length.unit === "mm") && (length.value > 1000)) ||
((length.unit === "cm") && (length.value > 100))
);
}
let length1 = { // 150ミリメートル
unit: "mm",
value: 150
};
console.log("length1: " + isGreaterThan1Meter(length1));
let length2 = { // 150センチメートル
unit: "cm",
value: 150
};
console.log("length2: " + isGreaterThan1Meter(length2));
解説
プログラムをよく見ながら、順を追ってif
文を整理していきましょう。
ステップ1:ANDでまとめる
まず、ミリメートル単位の長さを処理している、if
文のネストに注目しましょう。
if (length.unit === "mm") {
if (length.value > 1000) {
return true;
}
}
この2つのif
文は、外側の条件が成立し、かつ内側の条件も成立したかどうかをチェックしています。したがて、「AND条件(&&
)」を使えば1つにまとめられます。
if ((length.unit === "mm") && (length.value > 1000)) {
return true;
}
センチメートル単位の長さを処理しているほうのif
文についても……
if (length.unit === "cm") {
if (length.value > 100) {
return true;
}
}
同じようにすれば、1つにまとめられますね。
if ((length.unit === "cm") && (length.value > 100)) {
return true;
}
これで、4つあったif
文は2つに減りました。
ステップ2:ORでまとめる
ここまでで、if
文は次のようになっています。
if ((length.unit === "mm") && (length.value > 1000)) {
return true;
}
if ((length.unit === "cm") && (length.value > 100)) {
return true;
}
よく見ると、次のことが分かるでしょう。
- 条件が成立したときの処理内容は、どちらの
if
文も同じ(true
を返す) - 2つの
if
文の条件が、両方とも成立するケースはない(1つ目のif
文の条件が成立すると、その場でreturn
してしまうため)
そのため、次のように「OR条件(||
)」で1つにまとめてしまっても、結果は変わりません。
if (
((length.unit === "mm") && (length.value > 1000)) ||
((length.unit === "cm") && (length.value > 100))
) {
return true;
}
これで、if
文は1つになりました。でも、まだ終わりではありません!
ステップ3:式だけにする
if
文が1つになって、関数全体がどうなったか観察してみましょう。
function isGreaterThan1Meter(length) {
if (
((length.unit === "mm") && (length.value > 1000)) ||
((length.unit === "cm") && (length.value > 100))
) {
return true;
}
return false;
}
よく見ると、この関数は次のようになっています。
-
if
文の条件が成立したら、true
を返す - そうでなければ、
false
を返す
この処理には、少し冗長な部分があります。そもそも「if
文の条件が成立する」とは、「条件式がtrue
になる」ことだからです。
つまり、if
文をまったく書かずに、次のようにできます。
function isGreaterThan1Meter(length) {
return (
((length.unit === "mm") && (length.value > 1000)) ||
((length.unit === "cm") && (length.value > 100))
);
}
まとめ
今回は、4つあるif
文を「いくつまで減らせますか?」と出題しておいて、最終的に1つもなくなってしまうというのが答えでした。どうだったでしょうか?
プログラムは、無理をして短くまとめようとすると、かえって読みづらくなってしまうことも少なくありません。でも今回は、スッキリと分かりやすいプログラムにできたのではないかと思います。
if
文は「条件分岐」といって、プログラムの流れが枝分かれする部分にあたります。そのため、使いすぎると処理が複雑になり、動作確認も大変になってしまうかもしれません。ないほうがスッキリするif
文は、なくしてしまうのがおすすめです。
なお、if
文はJavaScriptに限らず多くのプログラミング言語に採用されている文法です。下記のページでは、C言語のif
文について取り上げています。
ほかのプログラミング言語についても気になるという人は、下記の本もチェックしてみてください。こちらでは、10種類のプログラミング言語を比較できます!
Discussion