• 締切済み

Perl if 文内にforeachを入れる場合

if ($pattern eq 'p2') { foreach $key (sort{ ($re_key{$b} <=> $re_key{$a}) || $b cmp $a } keys %re_key) { } else { foreach $key (sort{ ($b <=> $a) || $b cmp $a } keys %re_key) { } $pattern の選択で検索の種類を切り替えたいのですが、上のように指定するとコンパイルエラーになってしまいます。 foreach 文以降の処理は全く一緒なので、foreach 文の行だけ変更したいのですが、どうすれば良いですか?

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

foreach は対応する} までが一セット。 入れ子構造にはできるけど、互い違いにしたり、(やろうとしてるような)複数のforeachに一つの本文、等ということはできません。これはほとんどのプログラミング言語での基本です。 @sorted_key=sort~等としてリストに入れておくとか 「同じ処理」をサブルーチンにするとか 判定用の関数を(関数のリファレンスとかを使って)切り替えられるようにするとか で、前の質問は無視ですか?

全文を見る
すると、全ての回答が全文表示されます。
  • kuroizell
  • ベストアンサー率55% (95/170)
回答No.3

もしかして、こう? if ($pattern eq 'p2') { foreach $key (sort{ ($re_key{$b} <=> $re_key{$a}) || $b cmp $a } keys %re_key) { } } else { foreach $key (sort{ ($b <=> $a) || $b cmp $a } keys %re_key) { } }

全文を見る
すると、全ての回答が全文表示されます。
  • wormhole
  • ベストアンサー率28% (1623/5661)
回答No.2

構文上そのような事はできません。 foreachのリスト(sort~の部分)を変数にしてしまうとか 一緒の部分をサブルーチン化するとかすればよいかと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • notnot
  • ベストアンサー率47% (4856/10272)
回答No.1

中身をサブルーチンにしましょう。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 静的ハッシュの配列のキーに対応する値の数の多さ順で表示させたい

    ハッシュのキーに対応する値の数の多さ順で表示させたいと考え、下記の所まで試行錯誤しておりますが、どうにも思ったようにソートできずにおります。 #!/usr/bin/perl use strict; my(%a, $i, $j ,$allarray ,@keys ,@keys2 ,%hash ,%files ,$a_mumei_ref ,$key ,$value ,@value ,$x ,$files); # ハッシュの配列を静的に作る %a = ( '0' => [ qw(0) ], '1' => [ qw(1 1) ], '3' => [ qw(3 3 3) ], '7' => [ qw(7 7 7) ], '2' => [ qw(2) ], '4' => [ qw() ], '5' => [ qw() ], '6' => [ qw() ], '8' => [ qw(8 8) ], '9' => [ qw(9) ], ); @keys = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %a; #ハッシュのキーを数字順で表示 foreach (@keys){ print $_ ."\n"; } # 静的に作ったハッシュの配列を取り出してみる foreach $i (sort keys %a) { for ($j = 0; $j <= scalar(@{$a{$i}})-1; $j++) { print '$a{'. $i. '}['. $j. ']='. $a{$i}[$j]. ' '; } $allarray=scalar(@{$a{$i}})-1; print "No$i:kosuu:$allarray"; print "\n"; #配列の値の個数を調べその配列を作成 my($a_mumei) = $allarray; $a_mumei_ref = \$a_mumei; $files{"$i"}=($i,$a_mumei_ref); } #each関数で%filesの中身を表示 while ( ( $key , $value ) = each %files ){ print "key:$key value:$$value\n" ; } #試行錯誤 foreach $x (sort { $files{$b} <=> $files{$a} } keys %files){ print "$x => $files->{$x}\n"; } @keys2 = sort {$hash{$a} <=> $hash{$b}} keys %files; #@keys2 = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %files; #@keys2 = sort { $hash{$a} cmp $hash{$b} } keys %files; print "@keys2\n"; print "\n"; __END__; 私のイメージしておりますのは、ソートした結果がハッシュのキーに対応する値の数の多さ順で下記のように表示させたいのですが、 どのようにすれば可能でございますか、ご教授願えませんでしょうか key:3 value:2・・・この場合valueは配列の個数 key:7 value:2 key:8 value:1 key:1 value:1 key:9 value:0 key:2 value:0 key:0 value:0 key:6 value:-1 key:4 value:-1 key:5 value:-1

    • ベストアンサー
    • Perl
  • perlのpushについてです。

    お世話になります。perlのpushについてです。 データファイルを読み@XXに入れます。 実際はもうちょっと複雑なのですが、 foreach $DATA (@XX){$CHECK=''; ($A,$B)=split(/\,/$DATA); # $Bには改行コードを含んでいます。 if ($A==1){$A=2;$CHECK=1;} if ($A==2){$A=3;$CHECK=1;} if ($A==3 and $B==1){$A=1;$B=9;$CHECK=1;} if ($CHECK==1){ push(@N,"$A,$B");}else{ push(@N,"$DATA"9;} } として、@Nをファイルに出力すると1行目を除き、 行の先頭になぜか空白が付いてしまいます。 別のスクリプトで読むときに数字以外は削除というような 文を加えても削除できず、 if ( $A eq '1'){・・・・ としたときにマッチしてくれません。 よって、この最初にファイルに書き出す際に空白が付かないように したいのですが、何故付いてしまうのか?、回避方法は? ご指導頂けたら幸いです。 付いてしまいます。

    • ベストアンサー
    • Perl
  • perlのif文で・・・・・

    こんにちは。 お聞きしたいのですが、perlのif(A eq B)文で、crypt関数で暗号化した文字列の比較をしているのですが、画面に双方の変数をテスト表示をしてみて、AとBは一致しているにもかかわらず、このif文を飛ばしてしまいます。 暗号化した変数を使うのは初めてなんですが、何か可能性として考えられることはありますか? 自分でも考えられるチェックはしたつもりなんでが・・・

  • 配列要素の並べ替え

    $Res[$i]という配列に、数字の要素が入っているんですが、それを昇順で並べ替えして要素の間に/を入れたいのですが、 foreach (sort {$a cmp $b} keys %Res) { $Res2 = $Res[$i] + "/" } どうもこの記述では上手くいかないので、どなたか教えて下さい!!

    • ベストアンサー
    • Perl
  • if文内での計算

    現在、if文のなかで、 if ( a>= b ) としているのですが、 このbを4倍の値にしたいのです。 そのときにはどうしたらよいでしょうか。 if ( a>= b*4 ) でいいのでしょうか。

  • foreachについて

    phpを今勉強中なのですがforeachで少し分からない部分があります。 例えば(1)はnのある配列を消去するだけのプログラムでして、これを (2)のように書き換えてみると、全て表示されてしまい、(1)と同じ動きをしません。 phpマニュアルを読む限り同じ動きをすると思うのですが、array_keys($key1)の中に うまく一時配列のキーが入っていないように思います。 どうしてでしょうか? (1) <?php $food["y"]["bb"]= "k1"; $food["n"]["bb"]= "k2"; $food["n"]["cc"]= "k3"; $food["k"]["dd"]= "k4"; foreach($food as $key=>$key1){ foreach($key1 as $key2=>$key3){ if($key=="n") unset($food[$key][$key2]); } } echo "<pre>"; print_r($food); echo "</pre>"; ?> (2) <?php $food["y"]["bb"]= "k1"; $food["n"]["bb"]= "k2"; $food["n"]["cc"]= "k3"; $food["k"]["dd"]= "k4"; foreach($food as $key=>$key1){ foreach($key1 as $key2=>$key3){ if(in_array("n",array_keys($key1))) unset($food[$key][$key2]); } } echo "<pre>"; print_r($food); echo "</pre>"; ?>

    • ベストアンサー
    • PHP
  • サイト内検索CGI 更新新しい順に表示したい(2)

    http://okwave.jp/qa/q9269398.html ↑以前に質問したページです。 解決しないまま4週間たちそうなので(2)のページを作りました。 以前の質問はこんな感じでした↓ ──────────────────────────────────────────────────── CGIのSite_Searchを使っているのですが、公式サイトが閉鎖してしまっています。 Site_Searchの検索結果画面はこんな感じです。 http://nihon5ch.net/contents/ch5/site_search.cgi?mode=and&key=%A4%E2%A4%CE&list=40 これを、Key Search(http://www.kent-web.com/data/ksearch.html)のように、 update(Key Searchでいうところの日付)の新しい順に表示し、 できれば「新しい順/古い順」にソートできるようにしたいのです。 site_search.cgiの中身はこんな感じです。 http://delcy.jp/site_search.cgi ──────────────────────────────────────────────────── こちらのサイトのおかげで、 1回目の検索で、検索結果を新しい順に表示し、 検索結果画面の検索窓のところに、プルダウン「(ページの更新日が)新しい順/古い順」を設置する、という所まではできるようになりました。 今困っているのは、 プルダウンで「古い順」を選んでも、検索結果が古い順にソートされない事です。 ちなみに、print "$in{'sort'}<br>";を組み込んで、「古い順」で検索してみると、 値は「0(=古い順)」が表示されます。 ↓今回やってみたこと ──────────────────────────────────────────────────── ●$sortFlag = $in{'sort'}だけforeach ($top..$end) {の直前に入れたら 「500 Internal Server Error」が出たので以下のようにしました。 ●if ($sortFlag == 0) { @ret = sort{(split(/<>/,$a))[3] cmp (split(/<>/,$b))[3]} @hits; } else { @ret = sort{(split(/<>/,$b))[3] cmp (split(/<>/,$a))[3]} @hits; } @hits = @ret; はforeach ($top..$end) {の直後に入れました ↓今回カスタマイズした部分 ---------------- $sortFlag = $in{'sort'}; if($sortFlag == "") { $sortFlag = 1; } if ($sortFlag == 0) { @ret = sort{(split(/<>/,$a))[3] cmp (split(/<>/,$b))[3]} @hits; } else { @ret = sort{(split(/<>/,$b))[3] cmp (split(/<>/,$a))[3]} @hits; } @hits = @ret; foreach ($top..$end) { ($hfile,$htitle,$hsize,$hupdate,$hinf) = split (/<>/,$hits[$_]); if ($sortFlag == 0) { @ret = sort{(split(/<>/,$a))[3] cmp (split(/<>/,$b))[3]} @hits; } else { @ret = sort{(split(/<>/,$b))[3] cmp (split(/<>/,$a))[3]} @hits; } @hits = @ret; ──────────────────────────────────────────────────── よろしくお願いいたします。

    • ベストアンサー
    • CGI
  • if文の中に

    例えば if(a<0){ if(a<b) c=a+b } ように if文の中にif文を入れる事はできるのですか? また、if-else文はif() →else if() →elseと続きますが、 これ以降(4つ以上の選択肢) に繋げたい時はどうすればいいですか? 教えて下さい!

  • foreach文

    asort($ans); foreach($ans as $key => $value){ echo $key; } $keyの値を出力する数を制限したいのですが、教えて下さい。 仮に$keyにソートされて入っている値を上位から10件出力する。 while文で試しましたが、同じ値を繰り返すだけで駄目でした。 宜しくお願いします。

    • ベストアンサー
    • PHP
  • if文について

    if文を利用してリストの表示をしようとしています。 ドロップダウンリストは <SELECT name="type"> <OPTION value="all">指定しない </OPTION> <OPTION value="1">タイプA系列</OPTION> <OPTION value="2">タイプB系列</OPTION> となっています。 データはチェックボックスで1か空白で保存されていて、A系列は「s_1」「s_2」、B系列は「s_3」「s_4」「s_5」にチェックが入っているかどうかを振り分けしたいんです。 なので、ドロップダウンリストで「タイプA系列」を選択したら「s_1」「s_2」に1が入っている物のみ表示するというものです。 現在のところこの形です。 if ($FORM{'type'} ne 'all') { if ($FORM{'type'} eq '1'){ if ($s_7 || $s_8 eq 1) { ; } else { next; } }else{ if ($s_9 || $s_10 || $s_11 eq 1) { ; } else { next; } } } このようにやってみましたが全部表示されてしまいます。 どのように直したらOKでしょうか? お願いします。

    • ベストアンサー
    • Perl