- ベストアンサー
foreachについての続きの質問
- foreachについての続きに関する質問です。
- 特に$KU_REC->{KU_CODE}に値を入れる方法について不明点があります。
- 文字制限のため全てのコードを表示できませんが、足りない部分があれば追加します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
@BCOL に対しては, $KU_REC 経由で値を入れています. つまり, (1) push(@BCOL, {}); でプッシュしたハッシュへのリファレンスを (2) $KU_REC = $BCOL[$#BCOL]; で $KU_REC という変数に入れていますので, ここで $KU_REC->{KU_CODE} = $REC{KU_CODE}; $KU_REC->{KU_NAME} = $REC{KU_NAME}; を実行すると (1) でプッシュしたハッシュにデータが入ります. が, だったら最初から push(@BCOL, {KU_CODE => $REC{KU_CODE}, KU_NAME => $REC{KU_NAME}}); とすればいいということになりますが, その後でさらに各データに追加するのかなぁ? さらにいうと, その後の使い方によってはハッシュを使って $BCOL{$REC{KU_CODE}} = $REC{KU_NAME}; とすべきかもしれません.
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
高速化というよりは (C で言うところの) 構造体を作るためにハッシュを使いたいんだけどハッシュそのものは入れられないのでリファレンスを使っているという感じだと思います. ただ, どうも「なんというか」という感じになったりするわけでして, 例えば対象とする区コードや部コードを見付ける部分はサブルーチンに切り分けた方がいいんじゃないかなと思います. 例えば (このサブルーチンが正しいかどうかは知りませんが) sub findRecord(\@$$) { my ($records, $key, $value) = @_; foreach (@$records) { if ($_->{$key} eq $value) { $target = $_; last; } $target; } とすれば foreach $BU_RECt (@{$KU_REC->{BU}}) { if ($BU_RECt->{BU_CODE} eq $REC{BU_CODE}) { $BU_REC = $BU_RECt; $flg_find_bu = 0; last; } } は $BU_REC = findRecord($KU_REC->{BU}, 'BU_CODE', $REC{BU_CODE}); の 1行ですむ ($flg_find_bu の判定は defined $BU_REC で代用) ので読みやすくなりますよね. 区コードを見付けるところも $KU_REC = findRecord(\@BCOL, 'KU_CODE', $REC{KU_CODE}); と書けますし.
お礼
おっしゃるとおりですね。私も目が回りそうになるくらい何度もLOOP処理を見ましたが、サブルーチン化できるところは分けたほうが見やすいですね。あとはそうできない理由がないか、ちゃんと見て、できそうならトライしてみようと思います。ありがとうございました。
- Tacosan
- ベストアンサー率23% (3656/15482)
.... なんか, とってもすごいプログラムのような気がしてきました.... プログラムを解析するよりも「やりたいこと」を理解して最初から作り直した方がいいような気もしますが, そうも言ってられないと思いますので簡単に: データを出力したいだけであれば Dumpvalue というモジュールを使うのが最もお手軽だと思います. 気を抜くと全データが出力されて, 見ていられないという問題はありますが. 「@BCOL にはどんなデータがどのように並んでいるか」ですが, まず「どのように並んでいるか」は無視しちゃってかまわないと思います. また, 入っているデータについてはハッシュ (へのリファレンス) であることはわかっているので, そのハッシュでキーと値 (の意味) の対応を見ればいいと思います. つまり, @BCOL の各データは KU_CODE, KU_NAME, BU という 3つのキーを持つハッシュで, それぞれ「区コード」, 「区の名前」, 「その区に入っている部のデータ」に対応します. で, BU についてもやはり同様に順序を無視して入っているデータだけ考えればよいでしょう.
お礼
迅速な回答ありがとうございます。 でも、なんかだいぶ頭がすっきり整理されてきて、どこに新しい処理を入れなくてはいけないのか、がわかってきました。Dumpvalueをつかってもっと明確にしていきたいとおもいます。 しかし、PERLでは高速化するためにリファレンスを使ってるんだと思いますが、そのおかげでとっても入り組んだものになってしまいますね。わかりにくかったので、その部分だけ(区分、部コードを取得するところ)フローチャートにしてみるとA33枚になってしまいました(^^;
お礼
Tacosanさん、いつも的確な答えをありがとうございます。前回と同様、きっと答えていただける、とすごく期待しておりました(~~; さて、今回の件、前回より何度考えてもわからなくて、でも漠然とはそうかな、とつかめかけてたのですが、確証がほしくて投稿しました。しかしながら、頭で理解しても感覚としてはまだつかみきれていない状態で、まだまだ壁は厚いです。 なぜ○○しないのかなぁ、という点ですが、私にもいまいちつかめないですが、この後もデータが追加されるのは間違いありません。 push(@{$KU_REC->{BU}}, {}); $BU_REC = $KU_REC->{BU}->[$#{$KU_REC->{BU}}]; を行い、 $BU_REC->{BU_CODE} = $REC{BU_CODE}; $BU_REC->{BU_NAME} = $REC{BU_NAME}; とし、 foreach $BU_RECt (@{$KU_REC->{BU}}) { if ($BU_RECt->{BU_CODE} eq $REC{BU_CODE}) { $BU_REC = $BU_RECt; $flg_find_bu = 0; last; } } として、部コードに関しても同じように行っています。 ここまでくるともはや@BCOLにはどんなデータがどのように並んでいるのかわかりません(*_*)でもそれを解析しなくてはならないのです。 ここでまたまた質問です。@BCOLは配列ですよね? いま$BCOL[0]に{KU_CODE => $REC{KU_CODE}が入っているかと思うのですが、配列内に入っているハッシュのキーと値をログで出力する方法はあるのでしょうか? お礼なのに、質問しちゃってすみません・・・。こういう場合また新しくとぴをたてるほうがいいのかなぁ・・・。 よろしくお願いします。