- ベストアンサー
if文における複数条件の簡略化
はじめまして。 Perlを勉強中の者です。 if文中における複数の条件に関する質問があるのでお願いいたします。 if文中における条件が複数ある場合に条件を簡素化することは可能でしょうか。 下記がただ今作成しているプログラムの一部なのですが、2つ目のif文中には10通りの条件があります。同一のプログラム内に同じ条件をもつif文が他数箇所あるので何か良い解決方法を探しております。 サブルーチンも考えたのですが、どのようにif文の条件として用いてよいのかわからないため、ご教授お願いいたします。 if ($code eq $codetwo){ if ((($code eq 'i')&&($F1mean<900)&&(1600<$F2mean)&&($F2mean<3100))| (($code eq 'y')&&($F1mean<900)&&(1400<$F2mean)&&($F2mean<2800))| (($code eq 'e')&&($F1mean<900)&&(1400<$F2mean)&&($F2mean<3000))| (($code eq 'E')&&($F1mean<1100)&&(1400<$F2mean)&&($F2mean<2700))| (($code eq 'a')&&($F1mean<1100)&&(900<$F2mean)&&($F2mean<2300))| (($code eq 'x')&&($F1mean<1100)&&(800<$F2mean)&&($F2mean<2400))| (($code eq 'X')&&($F1mean<1000)&&(700<$F2mean)&&($F2mean<2300))| (($code eq 'c')&&($F1mean<1000)&&(600<$F2mean)&&($F2mean<2000))| (($code eq 'o')&&($F1mean<1000)&&(600<$F2mean)&&($F2mean<1600))| (($code eq 'u')&&($F1mean<1000)&&(400<$F2mean)&&($F2mean<1500))){ printf F0123VF "%5.3f %5.3f %s %s %s %s %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) ", $timeBeg, $time, $code, $word, $phctxt, $fileID, $F0mean, $F0ratio, $F1mean, $F1ratio, $F2mean, $F2ratio, $F3mean, $F3ratio; } }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
あらかじめ下記のような感じに連想配列に条件を指定しておいて、 $check{'i'} = " 900, 1600, 3100"; $check{'y'} = " 900, 1400, 2800"; $check{'e'} = " 900, 1400, 3000"; $check{'E'} = "1100, 1400, 2700"; $check{'a'} = "1100, 900, 2300"; $check{'x'} = "1100, 800, 2400"; $check{'X'} = "1000, 700, 2300"; $check{'c'} = "1000, 600, 2000"; $check{'o'} = "1000, 600, 1600"; $check{'u'} = "1000, 400, 1500"; if ($code eq $codetwo){ if ($check{$code}){ ($F1, $F2L, $F2H) = split(/\,/, $check{$code}); if ($F1mean < $F1 && $F2L < $F2mean && $F2mean < $F2H){ printf F0123VF "%5.3f %5.3f %s %s %s %s %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) ", $timeBeg, $time, $code, $word, $phctxt, $fileID, $F0mean, $F0ratio, $F1mean, $F1ratio, $F2mean, $F2ratio, $F3mean, $F3ratio; } } } 同じ条件での判定が複数箇所あるのであれば、 下記のようにサブルーチンを用意して… sub check{ local($F1, $F2L, $F2H) = split(/\,/, $check{$code}); $_[0] < $F1 && $F2L < $_[1] && $_[1] < $F2H; } 判定側で下記のように… if ($code eq $codetwo){ if ($check{$code} && &check($F1mean, $F2mean)){ printf F0123VF "%5.3f %5.3f %s %s %s %s %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) ", $timeBeg, $time, $code, $word, $phctxt, $fileID, $F0mean, $F0ratio, $F1mean, $F1ratio, $F2mean, $F2ratio, $F3mean, $F3ratio; } } こんな感じではいかがでしょう?
その他の回答 (1)
- moon_night
- ベストアンサー率32% (598/1831)
例えばこんな感じ。 $code eq $codetwo の部分はよく分からなかったのでそのままにしてます。 if ($code eq $codetwo){ if (code_q($code,$F1mean,$F2mean)) { printf F0123VF "%5.3f %5.3f %s %s %s %s %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) %6.2f (%3.2f) ", $timeBeg, $time, $code, $word, $phctxt, $fileID, $F0mean, $F0ratio, $F1mean, $F1ratio, $F2mean, $F2ratio, $F3mean, $F3ratio; } } sub code_q ($code, $F1mean, $F2mean) { return 1 if (($code eq 'i')&&($F1mean<900)&&(1600<$F2mean)&&($F2mean<3100)); return 1 if (($code eq 'y')&&($F1mean<900)&&(1400<$F2mean)&&($F2mean<2800)); return 1 if (($code eq 'e')&&($F1mean<900)&&(1400<$F2mean)&&($F2mean<3000)); return 1 if (($code eq 'E')&&($F1mean<1100)&&(1400<$F2mean)&&($F2mean<2700)); return 1 if (($code eq 'a')&&($F1mean<1100)&&(900<$F2mean)&&($F2mean<2300)); return 1 if (($code eq 'x')&&($F1mean<1100)&&(800<$F2mean)&&($F2mean<2400)); return 1 if (($code eq 'X')&&($F1mean<1000)&&(700<$F2mean)&&($F2mean<2300)); return 1 if (($code eq 'c')&&($F1mean<1000)&&(600<$F2mean)&&($F2mean<2000)); return 1 if (($code eq 'o')&&($F1mean<1000)&&(600<$F2mean)&&($F2mean<1600)); return 1 if (($code eq 'u')&&($F1mean<1000)&&(400<$F2mean)&&($F2mean<1500)); }
お礼
回答いただきありがとうございました。 無事にプログラムが完成いたしました。 説明不足で申し訳ありません。 $code eq $codetwo の箇所は意味をなさないことに気付き削除しました。
お礼
回答いただきありがとうございました。 無事にプログラムが完成いたしました。 予め連想配列に条件を指定しておくことは考えになかったので、他の値を抽出するさいにも応用して使用できるので良かったです。