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

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

ただいまの
回答率

90.86%

  • PHP

    18170questions

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

  • MySQL

    5215questions

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

条件式の効率的な書き方

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 366

realmccoy

score 87

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

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • lucker

    2017/12/13 09:13

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

    キャンセル

  • masaya_ohashi

    2017/12/13 09:43 編集

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

    キャンセル

  • ttyp03

    2017/12/13 09:51

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

    キャンセル

回答 4

checkベストアンサー

+3

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

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

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

// こんな感じで想定される値を作っておく
$results = [
  "miyabi" => ["kokugo" => 60, "sugaku" => 75],
  "realmccoy" => ["kokugo" => 75, "sugaku" => 75],
];

function get_kokugo ($results, $name) {
  // PHPでは存在しないキーを参照しようとするとエラーになるのでissetやarray_key_existsで確認する
  if (isset($results[$name]["kokugo"])) {
    return $results[$name]["kokugo"];
  }
  return 0;
}
var_dump(get_kokugo($results, "miyabi"));
// Int: 75

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


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

class Animal {
  __constructor($name, $nakigoe) {
    $this->name = $name;
    $this->nakigoe = $nakigoe;
  }
  public function meu () {
    return $this->nakigoe;
  }
}

$neko = new Animal('mike', 'myao');
$inu = new Animal('poti', 'bow');
$miyabi = new Animal('miyabi', 'hueee...');

function cry ($it) {
  echo $it->meu();
}

cry($miyabi);
// hueee...

こんな感じです。


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

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

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

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

 追記

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

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

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

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

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


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

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

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

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


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

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

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

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


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

GitHub - Ruler

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.86%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    18170questions

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

  • MySQL

    5215questions

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