- ベストアンサー
Perlでのデータ処理についての初歩的な質問
- Perlでデータ処理を行っている際の初歩的な質問について解説します。
- データ処理を進めて得られたデータについて、合計値を出力する方法を解説します。
- 複数のデータがある場合は、後ろのデータを足し合わせるルールに従って処理します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#! perl use strict; use warnings; my @names = qw(a b c d e); my $txt = q(.txt); for my $name (@names) { # 要るヤツ my $result = { Question1 => { 1 => 0, 2 => 0, 4 => 0, }, Question2 => { 2 => 0, 4 => 0, } }; open my $in, '<', qq($name$txt) or die $!; my $question; while ( my $line = <$in> ) { chomp $line; next unless $line; if ( $line =~ /^(\d+)→(\d+)$/ ) { next if exists $result->{$question}->{$1}; $result->{$question}->{$1} = $2; } else { $question = $line; } } close $in or die $!; open my $out, '>', qq(${name}_out$txt) or die $!; my $total; for my $questions ( keys %{$result} ) { $total += $_ for values %{ $result->{$questions} }; } print {$out} qq(total=$total\n); close $out or die $!; } exit; __END__ やっつけ度満点ですが、こんな感じでどうでしょ。
その他の回答 (4)
- g_p_
- ベストアンサー率53% (28/52)
すみません、 間違ってました。 >next if exists $result->{$question}->{$1}; >ココで該当するハッシュのキーが存在しなかったら、読み飛ばしているつもりなんですけど。 ぜんぜん読み飛ばしてませんね。not が抜けてます。 next if not exists $result->{$question}->{$1}; でした。 二度も書き込んで見逃してました。すみません。 もうお分かりでしょうが、要らないキーを設定するも良し、 必要なキーを設定するも良し、いくらでもやり方はあるって事ですね。 とにかく間違ってましたすみません。
お礼
うまくいきました! next if not exists $result->{$question}->{$1}; と my $result 以下の部分を書き換えることで色々なパターンに対応できますね. 丁寧にありがとうございました!
- g_p_
- ベストアンサー率53% (28/52)
>#要るヤツ >の部分って使わないデータを0にすればいいんですよね? >このプログラムの場合ではQuestion1の1,2,4とQuestion2の2,4以外のデータが足し合わされるということでいいでしょうか? いや逆です。 どこまで説明すれば良いかアレですが、 要は、ファイルを読む前に、 # 要るヤツ my $result = { Question1 => { 1 => 0, 2 => 0, 4 => 0, }, Question2 => { 2 => 0, 4 => 0, } }; で、結果を格納するハッシュを初期化していて、 next if exists $result->{$question}->{$1}; ココで該当するハッシュのキーが存在しなかったら、読み飛ばしているつもりなんですけど。 期待した結果が出なかったんですかね?
- g_p_
- ベストアンサー率53% (28/52)
>上のa.txtの場合だと"total=25"といった感じに なら、手っ取り早く、 これを for my $num ( sort keys %{$result} ) { my $total; $total += $_ for values %{ $result->{$num} }; print {$out} qq($num→$total\n); } これに my $total; for my $num ( sort keys %{$result} ) { $total += $_ for values %{ $result->{$num} }; } print {$out} qq(total=$total\n); でどうでしょ。 $total の宣言場所と出力位置を変えただけです。
お礼
わざわざありがとうございます! 追加で質問なんですけど,この場合って $total += $_ のところで,数字を順番に足していっているんですよね? もしも,Question1の1,2,4とQuestion2の2,4だけを足し合わせたい場合だとプログラムを結構変えないといけなくなりますか?
- g_p_
- ベストアンサー率53% (28/52)
こんなんでどうですか? #! perl use strict; use warnings; my @names = qw(a b c d e); my $txt = q(.txt); for my $name (@names) { my $result; open my $in, '<', qq($name$txt) or die $!; my $question; while ( my $line = <$in> ) { chomp $line; next unless $line; if ( $line =~ /^(\d+)→(\d+)$/ ) { next unless $question; $result->{$1}->{$question} = $2; } else { $question = $line; } } open my $out, '>', qq(${name}_out$txt) or die $!; for my $num ( sort keys %{$result} ) { my $total; $total += $_ for values %{ $result->{$num} }; print {$out} qq($num→$total\n); } close $out or die $!; close $in or die $!; } exit; __DATA__ 読み込むファイルとか出力する形式とか分からない部分もありますが、 大体こんな感じでよくないですか? 他にもうまいやり方はあるでしょうけど。参考までに。
お礼
ありがとうございます.きちんと動きました. 私の説明が下手くそで質問の意図が伝わらなかったかもしれませんが,私が出力したかったのはQuestion1の1から4までの数字とQuestion2の1から4までの数字をすべて足し合わせたものです. (上のa.txtの場合だと"total=25"といった感じに) うまく説明できずにすみません...
お礼
ありがとうございます. #要るヤツ の部分って使わないデータを0にすればいいんですよね?このプログラムの場合ではQuestion1の1,2,4とQuestion2の2,4以外のデータが足し合わされるということでいいでしょうか?