• ベストアンサー

値の比較を効率よく行う方法を教えてください

最近、Perlによるプログラミングを始めました。 いろいろ学習していて不明なことがあったので、質問させていただきます。 比較による処理の分岐で、毎回比較する変数名と値は決まっています。 変数には、if文の外でforなどの処理により毎回違う値が格納されています。 このとき、何も考えずに力技で書けば if ($value eq 'aaa' || $value eq 'bbb' || $value eq 'ccc' || $value eq 'ddd' ||・・・){ # 処理 } となると思います。 これでも、処理はできるのですが、比較する値が少ないうちはいいですが、多くなったとき効率が悪いと思います。 それに、スマートではないですし・・・。 これを、効率よく処理なおかつスマートに書ける方法があれば、教えてやってください。 初心者の質問で申し訳ないですが、よろしくお願いします。

  • Perl
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

ハッシュテーブル(連想配列)を使用するのが最も良い方法です。 サンプルを以下に示します。 ---------------------------- $tbl{'aaa'} = 1; $tbl{'bbb'} = 1; $tbl{'ccc'} = 1; $tbl{'ddd'} = 1; $tbl{'eee'} = 2; $tbl{'fff'} = 2; $value = 'aaa'; if ($tbl{$value} == 1){ printf("1の処理\n"); } if ($tbl{$value} == 2){ printf("2の処理\n"); } ---------------------------- $valueに'aaa','bbb','ccc','ddd'の何れかの値が入っているとき、if ($tbl{$value} == 1)が成立します。 $valueに'eee','fff'の何れかの値が入っているとき、if ($tbl{$value} == 2)が成立します。 上記以外の値が入っているときは、上記の条件が成立しません。 $valueに'xxxxxx'等をいれて確かめて下さい。

qoozy257
質問者

お礼

ありがとうございます、レスが遅くなりました。 早速試したところ、コードもすっきりしてよくなりました。 まだまだ覚えることがたくさんありそうです。 ありがとうございました。

その他の回答 (2)

回答No.3

私だったら…ですが。 (1)比較する値が少ない(5個以下ぐらい?)だったら正規表現による一括チェックを使います。  BLUEPIXY様のパターン…ですが、例だと「文字列を含む」判定になってしまうような…やるならこうですかね?  if ($value =~/^aaa$|^bbb$|^ccc$|^ddd$/){   # 処理  } (2)比較する値が多かったらハッシュを使う。  tatsu99様の方法が良いと思います。 (3)比較対象の文字にハッシュの要素名として不適合な文字が入る可能性があるなら配列を使う方法もあります。  @checktable = ("aaa","bbb","ccc","ddd");  みたいにして比較対象を用意。  for文で一つずつ$valueと比較。  同じ物があったらフラグを立てるなりする。  

qoozy257
質問者

お礼

比較対象が今10個あるので、コードが長くなるのがいやだったため、よい方法をお伺いしました。 でも、いろいろな方法があることには改めてプログラミングの奥の深さを感じます。 これから、皆さんに教えていただいたものを一つ一つ確認しながら試してみます。 ありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

if ($value =~ /aaa|bbb|ccc|ddd/o){ # 処理 } でどうでしょう、効率は、そんなに悪くはないと思いますが。

qoozy257
質問者

お礼

なるほど、こういうやり方もあるのですね・・・。 比較対象が、多くなったときはコードが長くなりそうですが、試してみます。 効率とコードの読みやすさのどちらをとるのかということになりますね。

関連するQ&A

  • 別シートの値を検索して一致したものを合計する

    excelvba初心者です。 お手数おかけします。 難問なのかどうかもよく分からず。。困っています。 シート1       シート2   シート3 AAA 100     AAA 50      BBB 20 BBB 200   CCC 150   CCC 30 DDD 300   QQQ 250   DDD 10 EEE 400     WWW 350  RRR 40 上記の値を決められた順番に別シートに集計したい(その時に、値を1/10にしたい) シート4 AAA 150 BBB 220 CCC 180 DDD 310 EEE 400 FFF 0 GGG 0 www 350 findでAAAを検索し見つかった値を ifにて条件分岐させるものをつくったものの プロシャーシーが大きすぎと言われてできません。 どなたか教えていただけないでしょうか。

  • byte変数の大小を効率よく比較したい

    2つのbyte変数の比較を行いたいのですが、 byte aaa = 0x00; byte bbb = (byte)0xff; if(aaa > bbb){ 処理 } のようにするとbyteの最上位bitは符号として扱われるため 0xff=-127となってしまい意図した結果が得られません。 unsigned byteなるものがあれば都合がよいのですが、javaではサポートしておらず困っております。 代替案として、 if(aaa&0xff > bbb&0xff) などとして、一度intへ変換後比較すれば可能ですが、int用のメモリ領域を作成しなくてはならず、非効率の気がします。 byte変数の比較で、他に効率のよい方法はりませんでしょうか?

    • ベストアンサー
    • Java
  • Perlでの比較表現について

    度々失礼します。 Perlでの比較表現について、例えば $a=aaa,bbb,ccc,ddd; $b=aaa,bbb; if($a =~ $b){ print "include!"; } としたときの結果は include! となり、比較に合致するのですが、 $a=aaa,\[bbb\],ccc,ddd; $b=aaa,\[bbb\]; if($a =~ $b){ print "include!"; } という条件で実行すると、比較に合致せず何も表示されません。 こういった場合、どのように対処すればよろしいでしょうか。 ご存じの方がおられましたらご教授下さい。

    • ベストアンサー
    • Perl
  • セレクトボックスの値を増やしたい

    お世話になります。 セレクトボックスのOPTION値を増やしたいのですが、何か良い方法はないでしょうか。 実現したいことは、ボタンを押したときにテキストボックスの値をセレクトボックスの最下部に表示したいということです。 <INPUT TYPE="text" NAME="add_txt" VALUE=""> <SELECT NAME="lst"> <OPTION VALUE="aaa">aaa <OPTION VALUE="bbb">bbb <OPTION VALUE="ccc">ccc </SELECT> <INPUT TYPE="button" NAME="ent" VALUE="実行"> ------------------ この状態からtextに"ddd"という値を入れて実行ボタンを押した後、 <SELECT NAME="lst"> <OPTION VALUE="aaa">aaa <OPTION VALUE="bbb">bbb <OPTION VALUE="ccc">ccc <OPTION VALUE="ddd">ddd </SELECT> このような状態にしたいのですが、なにか方法はありますか。 ご存知の方いましたら、回答お待ちしています。

  • 文字列の比較のはずなのに・・・

    「値の比較を効率よく行う方法を教えてください」で効率よい比較の方法を教えていただきましたものです。 早速試しているときに、おかしなことが・・・。 文字列が格納されている変数「$value」と「hogehoge」という文字列を比較しているのですが(本当は、もっと多く比較していますが、今は簡単にするために省略しました)、 $value eq 'hogehoge' としたときにサーバーエラーになり、 $value == 'hogehoge' としたときは、ちゃんと比較されて分岐もできています。 ??といった感じなのですが、これで正常ですか? 私としては、「数値は==」「文字列はeq」でと思っていたものですから・・・。 ご教授よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • バッチファイルでファイルを比較後他のフォルダにコピ

    次のようなファイル構成で C:\AAA     C:\BBB   \ccc      \ccc    abc.txt    abc.txt    def.jpg    def.jpg   \ddd      \ddd    ghi.txt    ghi.txt    jkl.jpg    jkl.jpg C:AAA\ccc\abc.txt と C:BBB\ccc\abc.txt を比較 C:AAA\ccc\def.jpg と C:BBB\ccc\def.jpg を比較 C:AAA\ddd\ghi.txt と C:BBB\ddd\ghi.txt を比較 C:AAA\ddd\jkl.jpg と C:BBB\ddd\jkl.jpg を比較 全てのファイルに対し比較後C:\CCC(別のフォルダ)に階層を含めコピーしたく for /R %%A in ("C:\AAA") do for /R %%B in ("C:\BBB") do if %%~zA NEQ %%~zB (goto A) :A echo NEQ としましたがループしてしまいました 比較後C:\CCC(別のフォルダ)に階層を含めコピーする方法も含め ご教授をい願いします

  • if($key){ ($key eq 'aaa') || ~~を複数縦に記述したい

    sub AAA {my($key)=@_; if($key){ ($key eq "aaa") || ($key eq "bbb") || ($key eq "ccc") || ($key eq "ddd") || &Error("$keyが不正です。"); } } のような形があるとして、$key eq "" の数が50個近くあるような場合、横に表示するのではなく縦に ($key eq "aaa") || ($key eq "bbb") || ($key eq "ccc") || ($key eq "ddd") || と、見栄えよく表示させたいのですが どのように記述すればよいのでしょうか。 また代替案などありましたらあわせてご教授頂けますと幸いです。

    • ベストアンサー
    • Perl
  • 【エクセル】空セルを埋める方法

    お世話になります。 下記のような表があります。 1行目:AAA,BBB,CCC,DDD 2行目:空セル,BBB,CCC,DDD 3行目:空セル,BBB,CCC,DDD 4行目:aaa,BBB,CCC,DDD 5行目:空セル,BBB,CCC,DDD ・・・ こんなパターンの行が結構あります。 空セル部分を下記のように埋めたいのですが 1行目:AAA,BBB,CCC,DDD 2行目:AAA,BBB,CCC,DDD 3行目:AAA,BBB,CCC,DDD 4行目:aaa,BBB,CCC,DDD 5行目:aaa,BBB,CCC,DDD てっとり早く埋める方法ありませんか? いまは、【ctrl+↓】 ⇒【↑】⇒【ctrl+D】を延々繰り返しています。 宜しくお願いいたします。

  • マッチしなかった時の値を取り出したい

    perl5.8.5を使っています。 次のような形で$1の値を表示させたいのですが(そのまま$strを表示させれば良いとは思いますが、とりあえず) $str = "aaa"; if ($str !~ /^(bbb|ccc|ddd)/) { print "t=".$1; } これだと$1に値が入ってきません。 この場合はどのようにすれば$strの「aaa」を取り出すことができるのでしょうか?

    • ベストアンサー
    • Perl
  • dosでサイズを比較して異なるファイルだけコピー

    dosで全フォルダ内のファイルサイズを比較して異なるファイルだけコピーしたい 次のようなファイル構成で AAAフィルダ    BBBフォルダ  cccフォルダ    cccフォルダ   abc.txt      abc.txt   def.jpg      def.jpg  dddフォルダ    dddフォルダ   ghi.txt      ghi.txt   jkl.jpg      jkl.jpg AAA\ccc\abc.txtとBBB\ccc\abc.txt AAA\ccc\def.jpgとBBB\ccc\def.jpg AAA\ddd\ghi.txtとBBB\ddd\ghi.txt AAA\ddd\jkl.jpgとBBB\ddd\jkl.jpg 拡張子は問わずそれぞれに対するファイルのファイルサイズを比較して 大きくても小さくても異なるファイルだけbbbフォルダ内に上書きコピー したくご教授をお願いします