foreachについて

このQ&Aのポイント
  • foreachは配列などの一連のスカラー値を持つリストから順に要素を取り出し、スカラー変数に代入してからブロック内の処理を繰り返します。
  • @BCOLは最初要素を含んでいない場合、foreachを実行しないでしょう。
  • $BCOLに{}を追加すると、新しい要素が@BCOLの最後に追加されます。
回答を見る
  • ベストアンサー

foreachについて

ポケットリファレンスより foreach[★](□){■} 配列などの一連のスカラー値を持つリスト□から順に要素を取り出し、スカラー変数★に代入してからブロック内の■を繰り返し実行します。リスト値□がなくなった段階で終了します。 とあります。今解析しているプログラムで下記のようなコードがあり、数点質問があります。(このコードの前にあるDBを呼んで、$RECにデータを返しています) undef @BCOL; my($KU_REC); while ($rc = $DBr->fetchrow_hashref) { $flg_find_ku = 1; foreach $KU_RECt (@BCOL) { if ($KU_RECt->{KU_CODE} eq $REC{KU_CODE}) { $KU_REC = $KU_RECt; $flg_find_ku = 0; last; } $KU_REC = $KU_RECt; } if ($flg_find_ku == 1) { (1) push(@BCOL, {}); (2) $KU_REC = $BCOL[$#BCOL]; } } (1)@BCOLは最初要素を含んでいないように思うのですが、リファレンスの(リストの値がなくなるまで)という部分をみて疑問ですが、リストに値がないのに、foreachの中をとおるのでしょうか? (2)たとえば、とおったとして、このロジックはおなじ区コードを見つけて、見つかればフラグを0にするという処理だと思うのですが、最初の一回目は(1)(2)をとおると思います。この処理が何をしているかわかりません。@BCOLに{}を入れるとどうなるのでしょうか? また、$#BCOLは配列の引数をあらわしているように見えるのですが、いったい何番目の意味なのでしょうか? (3)スカラー変数は基本的にmyなどで宣言するかと思うのですが、foreachで使われる変数$KU_RECtの定義がみつかりません。ということはこの場合変数定義はいらないものと思ってよいのでしょうか? 私が何か勘違いしている部分もあるかと思うのですが、わかる方、どうぞよろしくお願いいたします。

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

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

最初にコメントしておきますと, このプログラムはどうも「今一つ」な感じが否めなかったりします. 区コードを見付けたかどうかのフラグの変数名や値がおかしい (普通なら $found_ku のように過去形の名前を使うだろうし, 「見付けたら 1, 見付からなかったら 0」という値の設定をすると思う) ですし, こんなところでわざわざ普通の配列を使う使うのも謎. ハッシュ使えばいいのに. 閑話休題 順番は逆ですが (3): use の引数は通常「モジュール」と呼びますが, 小文字で始まるものは特別に「プラグマ」と呼ぶことがあります. それはともかく, foreach の変数であれば事前に my しなくても foreach my $KU_RECt (@BCOL) のようにその場で宣言することができます. この場合, その変数は foreach の中でのみ有効となります. (2): このような処理をしている理由はよくわかりません. $KU_REC に $REC{KU_CODE} で与えられる区コードを持つデータを取り出したいんでしょうけど, だったらなぜ素直にハッシュを使わないのかが謎です. my %BCOL; unless (defined $BCOL{$REC{KU_CODE}}) { $BCOL{$REC{KU_CODE}} = { KU_CODE => $REC_KU_CODE }; } $KU_REC = $BCOL{$REC{KU_CODE}}; ですむんですけどねぇ (本当はもっと短くできますが). で, if ($KU_RECt->{KU_CODE} eq $REC{KU_CODE}) というコードがある以上 @BCOL の中のデータは KU_CODE というキーを持つハッシュ (へのリファレンス) でなければならないのですが, 示されたコード中に設定している部分がないので「必要である」と判断しました ($KU_REC に @BCOL の中のデータのいずれかが入っているのですが, このデータはハッシュへのリファレンスですから $KU_REC->{} という形でアクセスできます. つまり $KU_REC->{KU_CODE} = $REC{KU_CODE}; という文で区コードを入れています).

cshoaucmoa
質問者

お礼

返答ありがとうございました。なんか、私の理解の段階がまだここに達していないように思いました。もう少しがんばります。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

なんかコードがちょっと足りないような.... (1): foreach $var (@BCOL) { .... } は, 配列内の値かそれともコピーした値かという違いを除けば for ($i = 0; $i <= $#BCOL; $i++) { $var = $foo[$i]; .... } と同じ動作をします (foreach だと配列内の値をそのまま指すので変数に代入すると配列の値も変わる). なので, 配列が空の場合には foreach 内の文は実行されずにその次を進みます. (2): {} は空ハッシュへのリファレンス. 配列 @BCOL に対して $#BCOL は @BCOL の最後の要素の添字. だから push(@BCOL, {}); $KU_REC = $BCOL[$#BCOL]; を実行すると「配列 @BCOL に空ハッシュへのリファレンスを追加し, 今追加した値を $KU_REC に代入する」ことになります. ん~, でも $KU_REC->{KU_CODE} = $REC{KU_CODE}; とかなんとかってコードがないと意味がないような.... (3): strict プラグマを使わなければ my を付けなくてもかまいません. 逆に, strict プラグマを使った場合には必ず my で宣言しなければなりません.

cshoaucmoa
質問者

お礼

返答ありがとうございます。理解したいと何度も読んだのですが、まだいまいち理解できていないところが・・・。 (1) やっぱり通らないのですね。ということは$KU_RECに値がはじめて入るのは(2)の部分になるのですね。 (2) 処理の中身としては理解したのですが、どういう意味があるのか、というところは以前不明です。@BCOLに空のリファレンスをいれる、とはkeyも値も空のものを入れる、ということですかね?それを追加したものを$KU_RECに代入すると、それに対するリファレンスは $KU_REC->{} となるのでしょうか?なぜそのような処理が必要なのでしょうか? (3) strict プラグマって use strict;という記述のことでしょうか?このモジュールの最初に記述があります。となるとやっぱり$KU_RECtに対してもmy($KU_RECt);の記述が必要になるのでしょうか?現状はないのですが・・・。 上記記述はそれ自体がさらにLOOPされていて、何度もこのロジックを通るので、さらにご指摘の通り、この記述の次に $KU_REC->{KU_CODE} = $REC{KU_CODE}; という記述があります。どういうところからこの記述が必要と思われたか、また聞かせていただけるとうれしいです。 ※if ($KU_RECt->{KU_CODE} eq $REC{KU_CODE}) { という記述がある限り、どこかで@BCOLの中に区コードが入るんだろうなと思うのですが、その記述がどれにあたるのかまだ見出せません・・・。

関連するQ&A

  • No.1316461 foreachについての続き

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=1316461 で投稿させていただいた内容の続きです。 いろいろ自分なりに吟味してみたのですが、なかなかしっくりきません。 >ん~, でも $KU_REC->{KU_CODE} = $REC{KU_CODE}; >とかなんとかってコードがないと意味がないような.... おっしゃるとおり上記コードがありました。(すみません。文字数エラーが出てしまったので、わからないところ以降は削除し、一部抜粋させていただいておりました) 場所は if ($flg_find_ku == 1) { (1) push(@BCOL, {}); (2) $KU_REC = $BCOL[$#BCOL]; } の次に $KU_REC->{KU_CODE} = $REC{KU_CODE}; $KU_REC->{KU_NAME} = $REC{KU_NAME}; という形で入っておりました。 ただ、どうして、この値が入ったからといって@BCOLに値が入るのかがわかりません。(正式には参照先が、なのかもしれませんが・・・) $KU_REC->{KU_CODE} = $REC{KU_CODE};とすると $KU_RECt->{KU_CODE} eq $REC{KU_CODE}になることがあるのでしょうか?というか、ログ等の結果から言えばあるはずなのですが、どこで@BCOLに対して値が入るのかわかりません。明示的に値を入れているのはpush(@BCOL, {});だけに見えるのです。裏を返せばpush(@BCOL, {});という記述方法以外で$KU_RECt->{KU_CODE}に値を入れる方法があれば、その表記方法を教えてください。 文字制限に引っかかるため、すべてのコードを表示することはできませんが、また足りないと思われるところがあれば、逐次抜粋しますので、よろしくお願いします。

    • ベストアンサー
    • Perl
  • perl キーの集計について foreach文

    @list=(20,25,24,32,28,20,28,24,20); という、ある組織の人間の年齢の配列を定義したとします。 そこで、 foreach $fld(@list){ $syukei{$fld}++; } というforeach文によって、年齢を「キー」として集計していくという説明を受けたのですが、いきなりスカラー変数の$syukeiが出てきて、さっぱりわかりません。 $syukei{$fld}++; という一行の意味を教えてくださらないでしょうか。 また、++という記号を使用していますが、これを別の書き方で書き換えることはできないでしょうか。

    • ベストアンサー
    • CGI
  • リファレンスをサブルーチンの戻り値にしてもOKですか?

    ■ サブルーチン内部で処理した結果を格納した、配列、ハッシュ、スカラーなどのデータを戻り値として利用する必要があります。その場合、どうするのが標準的なやり方でしょうか? ■ return (配列へのリファレンス, ハッシュへのリファレンス, スカラー); などとやってしまっても問題はないでしょうか? ■ 下のプログラムを試したところ、予想に反しちゃんと 「31415」と表示されました。 #!/usr/bin/perl -w sub subroutine{ my @a = (3, 1, 4, 1, 5); return \@a; } my $b = subroutine{}; print @$b; ■ サブルーチン内部で使用した変数へのリファレンスをサブルーチン 外で使っていいのだろうか? サブルーチンの処理が終了した時点でサブルーチン内部で使用した 変数はメモリーから消去されるのかと思ったものですから。

    • ベストアンサー
    • Perl
  • if elsif 構文と複数の配列の使用

    if elsif の構文で、複数の配列を使ったマッチングで分からないところがあり、質問させていただきたいと思います。 たとえば通常ifを使って$_ に対してある配列すべての要素をマッチングさせるとすると、 foreach my $value (@list){ if($_ =~ /$value/ ){ do something}} となると思います。 私が書きたいスクリプトは以下のようなものです。 $_ にたいして、初め (if で)配列1のすべての要素を探し、それがなかったら(elsif)配列2のなかから探し、それでもなければ配列3の中から。。。。。。というものです。 foreach my $value1 (@list1){ if($_ =~ /$value1/ ){ do something} elsif {foreach my $value2 (@list2){ if($_ =~ /$value1/ ){ do something}} 感覚的にはこのような感じになると思うのですが。。。。 このelsifの部分から2つめの配列を使ったマッチングを行いたいのですが、elsif ( )のなかにどのように記述すれば 動く様になるでしょうか?

    • ベストアンサー
    • Perl
  • forEachをIEで使う方法はありますか?

    下記のコードは、javascriptのforEachを使って、配列の要素に対して順に処理をしていくものです。 forEachはFirefoxやChromeには対応していてInternetExprolerでは対応していないところまでは 調べて分かったのですが、その対策が分かりませんでした。 InternetExprolerでも動かすためにはどのようにしたらよいのでしょうか。 <html lang="ja"> <head> <title>テスト</title> </head> <body> <script type="text/javascript"> function aaa() { var ary = ["1", "2", "3"]; ary.forEach(bbb); function bbb(ccc) { alert(ccc); } } aaa(); </script> </body> </html>

  • foreachで多次元配列を生成

    こんにちわ。 配列をforeachでループさせて、それを多次元配列に入れていくことは可能でしょ うか? 例えば以下のようなデータがあるとします。 ---meibo.dat-------- c21<>田中<>21<>東京 c22<>佐藤<>22<>大阪 -------------------- ---test.php----------------------------------------------------- <? $list_meibo = file("meibo.dat"); foreach($list_meibo as $temp){    $i=split("<>",$temp);    $a=array($i[0] => array("name"=>$i[1],"age"=>$i[2],"ad"=>$i[3]),); } ?> ------------------------------------------------------------------- これでは $a=array("c21"=>array("name"=>"田中","age"=>"21","ad"=>"東京"), "c22"=>array("name"=>"佐藤",age"=>"21","ad"=>"大阪"),); という具合になってくれないでしょうか? これでいくと、配列の最後の要素のみデータに残ります。 どのようにしたらよいでしょうか? ご教授お願いします。

    • ベストアンサー
    • PHP
  • foreachとかの勝手な省略?

    PHP初心者です。 foreachを使うときに、参考サイトのソースを見て???だったのですが、 例えば以下の場合に foreach($_POST['hoge'] as $key => $val){ echo "$key : $val \n"; } とありますが、hogeは自分で決めたものなので分かるのですが、 見に覚えの無い$key => $valといった変数で動作しています。 $keyや$valは自分で定義した覚えはありません。 調べると$keyは分かりませんが、$valはvalueの省略みたいな記述がありました。 また、他には更に短縮され、$kとか$vしか記述されていないソースもあり、 試すとこれでも正常に動いています。 これはどういうことなのでしょうか? 何か決まりがあるのでしょうか。 ちなみに、チェックボックスの配列取得の定義に使いました。 私からはただ勝手に短縮しているようにしか見えず納得いきません。 お詳しい方、どなたかアドバイス頂けないでしょうか。 宜しくお願いします。

    • ベストアンサー
    • PHP
  • 複数の配列の全ての組み合わせを表示する方法

    複数の配列が定義されており、その各々から一つづつ要素を選んで出来る組み合わせの全てを表示したいのですが、その際に、foreachを単にネストするのではなく、より効率的方法や関数は何かありませんでしょうか。 たとえば、 @list_a = qw(1 2 3 4) @list_b = qw(a b c d) @list_c = qw(x y z) の3つの配列の全て組み合わせ、例えば、 1ax 1ay 1az 1bx 1by 1bz 1cz ... 4dy 4dzを全て表示させるプログラムを作成したいと思っています。 foreach $a (@list_a){ foreach $b (@list_b){ foreach $c (@list_c){ ... のようにforeachをネストすればよいのですが、配列の数がとても多い場合を考えています。 宜しくお願い致します。

    • ベストアンサー
    • Perl
  • foreachで一致した説明文を表示(初心

    この間ポケモン図鑑について質問させていただいた者です。(ID違いますけど^^; http://oshiete1.goo.ne.jp/kotaeru.php3?q=1649007 変な質問をしてるかもしれませんm(_ _)m @list内には 手持ち・・(略)<>あくしゅう<> ほのお・こお・・<>あついしぼう<> 戦頭に出ると・・<>あめふらし<> このように1つ目に説明文、2つ目に(特性の)名前が入っています。 それを、 foreach(@list){ ($content,$name)=split(/<>/); } こんな感じでスカラー変数に代入してるのですが、 各ポケモンのデータを表示するページで説明文を表示するにはどうすればいいのでしょうか? 「$end_tokuse」というスカラー変数にあらかじめ各ポケモンの特性の名前は入っていて、それを上の処理と一致するか、しないかでこんな感じで print <<EOM; <table><tr><td> EOM ここに上の処理を print <<EOM; </td></tr></table> EOM 持って来て表示させようかと思っていたのですが、表示するデータの量がほかにもたくさんありすぎていちいち切っていると 編集が大変面倒になるので、一致した説明文をスカラー変数に代入して print <<EOM; <table><tr><td> $setume </td></tr></table> EOM このようにしたいのですが、どうすればいいかわかりません。 一致した説明文をスカラー変数に代入して表示させるにはどうすればいいですか。 わかりにくいですがよろしくお願いします。

    • ベストアンサー
    • Perl
  • 配列作成時の区切り文字について

    こんばんは。 perlをはじめて一ヶ月あまりの初心者です。 いま「続・初めてのPerl」という本で勉強しています(オライリーの本です)。 mapの使用例として以下のコードがあるのですが、 理解できず、気になって仕方ない箇所があります(以下のコードです)・・・。 -------------------------------------------------------------- my %provisions = ( 'The Skipper' => [qw(blue_shirt hat jacket preserver sunscreen)], 'The Professor' => [qw(sunscreen water_bottle slide_rule radio)], 'Gilligan' => [qw(red_shirt hat lucky_socks water_bollte)], ); my @remapped_list = map{ [ $_ => $provisions{$_} ]; } keys %provisions; -------------------------------------------------------------- [ $_ => $provisions{$_} ]; の部分で配列へのリファレンスを作っているのですが 要素を区切るのに、どうして「=>」を使うのでしょうか? 配列で要素を格納するときは「,」で区切るのではないでしょうか? @remapped_listのダンプを取ってみましたが、 「=>」ではなくて「,」で区切っても、 メモリの番地や配列の内容はまったく同じ結果になりました。 リファレンスや、無名配列、無名ハッシュは理解しているつもりですが、 知らない用法がまだあるのかな・・・。 もしご存知の方がいらっしゃいましたら、教えていただきたいです。 宜しくお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう