質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

1958閲覧

条件式の効率的な書き方

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

2クリップ

投稿2017/12/12 10:16

編集2017/12/13 11:01

現在、下記のように条件式を積み重ねていく処理があるのですが、

if(a===1){
}elseif(a===2){
}elseif(a===3){
}elseif(a===4){

条件式がそれこそ500個など大量になった場合、処理効率が悪い方法だと思います。
※新しく条件が追加された場合、上記のように条件式を追加していくという運用をしています。

通常、このような処理・記述を効率化したい場合、どのような記述方法が考えられますでしょうか?

miyabi-sun👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/12/12 10:58

array_mapとか?
otn

2017/12/12 11:43

自分自身とは常に等しいのでは?
退会済みユーザー

退会済みユーザー

2017/12/13 00:13

この人たち、何言ってるの?と思うの、オレだけ?
masaya_ohashi

2017/12/13 00:43 編集

これ、ifで見ている変数がifごとに違うんですが、a===1、a===2とか、同じaで値がどれかを見るifではないのでしょうか?意図通りの質問ですか?
ttyp03

2017/12/13 00:51

左辺は変動するのでしょうか?常にaではない?
guest

回答4

0

ベストアンサー

ポリモーフィズムを使いましょう。
PHPでは一般的に以下の2つの手段が用いられます。

  • 値が欲しい: 連想配列のキーとして用意して探索
  • 処理を実行したい: オブジェクトを差し替えて同名のメソッドを実行する

1個目はそのまんまです。

PHP

1// こんな感じで想定される値を作っておく 2$results = [ 3 "miyabi" => ["kokugo" => 60, "sugaku" => 75], 4 "realmccoy" => ["kokugo" => 75, "sugaku" => 75], 5]; 6 7function get_kokugo ($results, $name) { 8 // PHPでは存在しないキーを参照しようとするとエラーになるのでissetやarray_key_existsで確認する 9 if (isset($results[$name]["kokugo"])) { 10 return $results[$name]["kokugo"]; 11 } 12 return 0; 13} 14var_dump(get_kokugo($results, "miyabi")); 15// Int: 75

このようにすれば選択肢がどんなに増えてもif文1個で事足ります。
例えばエラーコードとエラー文言の対応表をMySQLに格納して取りに行く設計にすれば、まるでMySQLをIF文の情報置き場であるかのように振る舞います。


2個目はオブジェクト指向(OOP)でよく使われる手法です。

PHP

1class Animal { 2 __constructor($name, $nakigoe) { 3 $this->name = $name; 4 $this->nakigoe = $nakigoe; 5 } 6 public function meu () { 7 return $this->nakigoe; 8 } 9} 10 11$neko = new Animal('mike', 'myao'); 12$inu = new Animal('poti', 'bow'); 13$miyabi = new Animal('miyabi', 'hueee...'); 14 15function cry ($it) { 16 echo $it->meu(); 17} 18 19cry($miyabi); 20// hueee...

こんな感じです。


注意点としては、
処理が分散するので基本的にコード量が増えます。

  • 新しく配列やクラスを定義する必要がある
  • 持ってくる引数や変数、メソッド等も増える

下手な管理をしていると処理は色んな所に散らかって読みづらくなってしまいます。
このグループはこの点では同じだよね、という共通点を上手く抽出して抜き出す(抽象化)が必要ですし、
抜き出した共通部分が何かに適切な名前付けが必要です。

半年後の自分に、このクソコード書いたのは誰というネタが多くありますが、
大抵は自分の名付けた名前がまずくて連想出来ないからです。

長くやっていれば勘所がつくようになるので、
あれは良かったのだろうか、悪かったのだろうか…という反省を行うようにしてください。
書籍「リーダブルコード」を読むことでもセンスは磨かれると思うのでオススメします。

投稿2017/12/12 11:42

編集2017/12/12 11:53
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

条件式がそれこそ500個など大量になった場合、処理効率が悪い方法だと思います
処理・記述を効率化したい場合、どのような記述方法が考えられますでしょうか?

数が多い条件式を効率的に記述するには、
まず、配列連想配列を使うのがよくある手法です。

処理内容も大きく変わる場合には、別オブジェクトに分け、
ポリモーフィズムで分岐させます。

しかし、これらはすでに回答されているので、
難しくなりますが、別の方法も説明しておきましょう。


条件式が500個もあって、仕様上どうしても省略できない前提なら、
(プロダクション)ルールエンジンを作る(使う)ことも視野に入れます。

とくにたとえば、毎月500個の別の条件式を使うとか、
変更が多い場合には、最初の作成コストは掛かりますが、
システムを作ってしまった方が、その後の変更コストは下がります。

というのも、たとえば一ヶ月や一年経って、内容を忘れてしまってから、
また500個の条件式をチェックするのは、非常に労力が掛かるからです。

携帯電話の料金とか、ああいうビジネスルールが非常に複雑な場合、
ルールエンジンが実務で実際に利用されているようです。


ルールエンジンはそこそこ難しいので、実装方法の詳細は省略しますが、
概要だけ言うと、条件分岐をIF文などで直接書くのではなく、
条件分岐させるルールをDSLに分離して、
ルールエンジンがそのDSLを読み取って、代替計算します。

DSLにはIF文などがないので、記述量が減るし、場合によって、
DSLを仕様に対応させて、直接読み下せるようになるのがメリットです。

もし、自力で実装する場合、Prologのような宣言的言語を参考にします。
しかし率直に言うと、Prologは難解です。少なくとも、初心者向けではないです。

だから、JBossなどOSSのBRMSを利用する方法も、ひとつの選択肢でしょう。


(追記)
JBossはJavaなので、PHPで完結させたい場合、どうすればいいか。

GitHub - Ruler

「Ruler」というPHPのルールエンジンがあり、
GitHubで公開されているので、
これを使うなり、参考にして実装するなりします。

投稿2017/12/13 11:24

編集2017/12/13 11:41
LLman

総合スコア5592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

a,b,c・・・とチェックする要素がかわっていくのであれば
それぞれを排他的な条件設定をしているので
現在のifelseifelseif・・・で問題ないと思います

追記

命題を書き換えるとこういうことです

if(a===1){ 処理1 }elseif(b===2){ 処理2 }elseif(c===3){ 処理3 }elseif(d===4){ 処理4 }

↓↓↓

if(a===1){ 処理1 } if(a!==1 && b===2){ 処理2 } if(a!==1 && b!==2 && c===3){ 処理3 } if(a!==1 && b!==2 && c!==3 && d===4){ 処理4 }

elseの処理は前方の条件の偽をすべて継承していくるわけです。
元の書き方のほうが効率的だとわかりますよね?

投稿2017/12/13 00:43

編集2017/12/13 02:42
yambejp

総合スコア114839

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

通常、このような処理・記述を効率化したい場合、どのような記述方法が考えられますでしょうか?

記述方法というより、そのように判定が増えることになる設計を見直すべきでしょうね。

投稿2017/12/13 02:31

sazi

総合スコア25195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問