プロが教える店舗&オフィスのセキュリティ対策術

javascript初心者です。

下記のように7つの変数を利用した組み合わせで、表示内容を変えるjavascriptを組んでいます。
IF文で組んでみたところ、下記のように18通りのIF文になってしまいました。
このjavascriptについては、変数を変えて1ページに10ケ所に配置するため、クライアントマシンは、180通りのIF文計算をすることになるため、簡素化したいと考えています。

switch文だと条件分岐を簡素化出来そうですが、例文では、変数がひとつの場合の例しか載っておらず、複数の場合の記載例がありませんでした。

もっと効率的な方法があると思うため、IF文に限らず良い方法をご指導頂きたくお願いする次第です。

宜しくお願い致します。

var a1
var a2
var a3
var a4
var a5
var a6
var a7


if (a1=="") {
document.write("1の作業"); }
else if (a2<a3*50) {
document.write("2の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5<=1000) && (a6>=300) && a7="") ) {
document.write("2の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5<=1000) && (a6<299) && a7="") ) {
document.write("3の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5>1000) && (a6>=300) && a7="") ) {
document.write("4の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5>1000) && (a6<299) && a7="") ) {
document.write("5の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5<=1000) && (a6>=300) && a7="") ) {
document.write("6の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5<=1000) && (a6<299) && a7="") ) {
document.write("7の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5>1000) && (a6>=300) && a7="") ) {
document.write("8の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5>1000) && (a6<299) && a7="") ) {
document.write("9の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5<=1000) && (a6>=300) && a7="1") ) {
document.write("10の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5<=1000) && (a6<299) && a7="1") ) {
document.write("11の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5>1000) && (a6>=300) && a7="1") ) {
document.write("12の作業"); }
else if ((a2<a3*50) && (a4>=1000) && (a5>1000) && (a6<299) && a7="1") ) {
document.write("13の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5<=1000) && (a6>=300) && a7="1") ) {
document.write("14の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5<=1000) && (a6<299) && a7="1") ) {
document.write("15の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5>1000) && (a6>=300) && a7="1") ) {
document.write("16の作業"); }
else if ((a2<a3*50) && (a4<1000) && (a5>1000) && (a6<299) && a7="1") ) {
document.write("17の作業"); }
else {
document.write("18の作業"); }

A 回答 (5件)

現代のコンピュータは十分に高速ですので,数十人以上が同時実行するような負荷が高めのコードでないかぎり,些末な速度差にこだわってマニアックなコードを書くよりも,他の人にもロジックが分かりやすく保守しやすいコードを書くのがプログラミングの基本です。



質問者ご自身は,質問文に載せたコードに満足していらっしゃらないようですけれど,私の感想としては,冗長ではあるものの「どの条件のときに何をするか」が分かりやすくコード化されているので,回答No.2のコードよりも質問文のコードの方を好ましく思っています。

> 画像の決定表3列目に「90%がここ」と記載していますが、
> ELSE文の早い位置に(3番目など)持ってくることにより、
> ブレイクが早まり、結果 軽くなるものと思っています。

というのも,現代のプログラミングからすると発想が違うでしょう。
早いうちに分岐させてしまうコードの方が「ロジックの見通しがよくなる」からそうするのであり,些末な速度差にはこだわらなくてよいはずです。

--------
以下,回答No.2の補足で提示していただいた決定表を踏まえてサンブルコードにしてみました。
ただしこのコードは,決定表が参照資料としてすぐそばに添えられていてようやく成立するコードだと思います。決定表が添付されていないのであれば,元の質問文に載せられていたコードの方が私は好みです。

if (aa1 == true) {
作業1; }
else if (aa2 == true) {
作業2; }
else if (aa3 == true && aa4 == true) {
作業3; }
else if (aa3 == true && aa4 == false) {
if (aa5 == true) {
作業3; }
else {
if (aa7 == true) {
作業5; }
else {
作業8; }
}
}
else if (aa3 == false && aa4 == true) {
if (aa6 == true) {
作業4; }
else {
作業7; }
}
else if (aa3 == false && aa4 == false) { //★
if (aa5 == true) {
if (aa6 == true) {
作業4; }
else {
作業7; }
}
else {
if (aa8 == true) {
作業6; }
else {
作業9; }
}
}

なお,上記コード中の //★ の箇所の行は,単に else { でもよいのですが,
aa3 と aa4 の真偽の組合せ4パターンをすべてチェックしている,と明示する方が明らかに分かりやすいと判断したため,上記のようにコーディングしました。
    • good
    • 0
この回答へのお礼

大変ありがとうございます。
素晴らしいソースをご提示頂き本当に助かります。
true false で分けていくんですね。
大変勉強になりました。
おっしゃる通り、ぱっと見ただけでは、どのような基準で作ったのか分かりづらいため、決定表とセットで用いる必要があると思います。
早速使用させて頂きます。
本当にありがとうございました。

お礼日時:2013/07/16 21:37

組み合わせ表 作ったのですね。


この表は、普通の組み合わせ表と考えると、矛盾しているところが多いのですが、
aa1の判断が最も優先順位が高く、aa8が最も低い、という解釈でよいのですね。

この表を、整理してみました。図のように3つに分けて考えると、すっきりします。
(間違っていないか、確認してください。)
「条件分岐(IF文)の簡素化」の回答画像5

この回答への補足

>(間違っていないか、確認してください。)
ありがとう御座います。この通りです。
確かにこのように分けるとすっきりしますね。
大変勉強になります。考え方がわかってきたような気がします。

補足日時:2013/07/16 16:49
    • good
    • 0

結局、a2、a4、a5、a6、a7とも、ある数より大きいか小さいか(a7は等しいか異なるか)の2通りの条件しかないのですよね。



でしたら
k=-(a2<a3*50)*16 - (a4<1000)*8 - (a5<=1000)*4 - (a6<300)*2 - (a7="1")
として、kの値に応じてswitch 分で分岐すればよいでしょう。

それともa6,a7は3通りの値ですか? だとしたらkをつぎのようにすればよいです。
k=-(a2<a3*50)*36 - (a4<1000)*18 - (a5<=1000)*9 - ((a6<299)+(a6<300))*3 - (a7=="")-(a7=="1")

しかし、この分岐は複雑ですが、正しく書かれていますか?
次のような、組み合わせテーブルを作って検討したほうがよいと思います。
http://blog.livedoor.jp/prjmng/archives/52154317 …
    • good
    • 0
この回答へのお礼

テストしてみました。(a6<300)で、true=1 or false=0として計算可能とは知りませんでした。
目から鱗です。素晴らしいアイデアですね。
この方法であれば、クライアント負担も最小で済みそうです。ご指導有難うございました。

お礼日時:2013/07/16 21:30

回答No.1の最後で指摘のあったとおり,



> else if (a2<a3*50) {
> document.write("2の作業"); }

のif条件が正しくは a2 >= a3*50 の間違いであったと仮定し,
かつ,
a7="" や a7="1" が正しくは a7=="" や a7=="1" だったと仮定するなら,
コーディング例としてはこんな感じ。

if (a1=="") {
document.write("1の作業"); }
else if (a2 >= a3*50) {
document.write("2の作業"); }
else if (!(a7 == "" || a7 == "1")) {
document.write("18の作業"); }
else {
if (a7 == "") {
if (a4 >= 1000) {
if (a5 <= 1000) {
if (a6 >= 300) {
document.write("2の作業"); }
else {
document.write("3の作業"); }
}
else {
if (a6 >= 300) {
document.write("4の作業"); }
else {
document.write("5の作業"); }
}
}
else {
if (a5 <= 1000) {
if (a6 >= 300) {
document.write("6の作業"); }
else {
document.write("7の作業"); }
}
else {
if (a6 >= 300) {
document.write("8の作業"); }
else {
document.write("9の作業"); }
}
}
}
if (a7 == "1") {
if (a4 >= 1000) {
if (a5 <= 1000) {
if (a6 >= 300) {
document.write("10の作業"); }
else {
document.write("11の作業"); }
}
else {
if (a6 >= 300) {
document.write("12の作業"); }
else {
document.write("13の作業"); }
}
}
else {
if (a5 <= 1000) {
if (a6 >= 300) {
document.write("14の作業"); }
else {
document.write("15の作業"); }
}
else {
if (a6 >= 300) {
document.write("16の作業"); }
else {
document.write("17の作業"); }
}
}
}
}

--------
そもそも,18通りの異なる動作をさせたいわけではなく,
させたい動作のパターンはもっと少ないようであるなら,
条件と動作の関係を1枚の決定表にまとめていただければ
効率的な解答例が提示できるでしょう。
(決定表をご存じなければ,Google画像検索してみてください)

この回答への補足

有難うございます。
例示頂きました式を拝見いたしました。
&&を使わないで出来ることに感銘を受けました。
当方の勉強不足を恥じ入るばかりです。

>そもそも,18通りの異なる動作をさせたいわけではなく,
>させたい動作のパターンはもっと少ないようであるなら,
>条件と動作の関係を1枚の決定表にまとめていただければ
>効率的な解答例が提示できるでしょう。

本当にありがとうございます。大変恐れ入ります。

お言葉に甘え、内容を大幅に見直した上で、条件、決定表を作りました。

下記の形になります。

http://nc.pro.ne.jp/okweb/

Y N 以外に●を入れておりますが、これは「YでもNでもどうでもいい」という意味です。

作れば作るほど途方にくれております。

もし宜しければあと少しのお力添えをお願い申し上げます。


追伸
画像の決定表3列目に「90%がここ」と記載していますが、このjavascriptを使用する殆どのユーザーが該当するのが、この3列目です。
ELSE文の早い位置に(3番目など)持ってくることにより、ブレイクが早まり、結果 軽くなるものと思っています。

補足日時:2013/07/15 21:24
    • good
    • 0

こういうときのうまいやり方、となると、「論理を理解して整理する」しか無いでしょう。



例えば

if ( A ) {
} else if ( ! A && B ) {
}
だったら、 elseへ来た段階で、 ! A は確実なので
if ( A ) {
} else if ( B ) {
}
でよい。

if ( A && B ) {
} else if ( A && C ) {
}
なら
if ( A ) {
// この中は A であることは決定している。
if(B) { // なので、 A && の判定は不要
}else if (C) {
}
}
とか

ちなみに、
else if (a2<a3*50) { // ここで a2<a3*50なので
document.write("2の作業"); }
// これ以降は「a2<a3*50):は常に偽であり、この後のif節が実行されることはありません。
// どちらかが間違いです。
else if ((a2<a3*50) && (a4>=1000) && (a5<=1000) && (a6>=300) && a7="") ) {
document.write("2の作業"); }
    • good
    • 0
この回答へのお礼

有難うございます。
やはり、IF文しか手はないのですね。
else文の考え方の件、大変勉強になりました。本当に有難うございました。

その後、再度見直したところ、さらに複雑になることが分かりました。
考え方を整理し、なるべく軽くできるように考えてみます。
有難うございました。

お礼日時:2013/07/15 21:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!