- ベストアンサー
csvデータの列に%で区切った項目があります
- csvデータ内にはaaaは3個だけですが下記コードで実行するとaaaが6個と計算されます。bbb、ccc、dddの個数は正確に計算されます。
- $find = 0; for($d = 0 ; $d < @TEST ; ++$d) { (@ITEM) = split(/\,/, $TEST[$d]); @T = split(/\%/, @ITEMD[2]); #csvデータ内項目%区切り if($in{'item'} eq @T[0]) #@T[0]にaaaが入ります { if(($in{'item2'} eq "") or ($in{'item2'} eq "全て")) { @FIND[$find] = $TEST[$d]; $find++; } elsif($in{'item2'} eq @T[2]) { @FIND[$find] = $TEST[$d]; $find++; } if($in{'item2'} eq @T[1]) { if(($in{'item3'} eq "") or ($in{'item3'} eq "全て")) { @FIND[$find] = $TEST[$d]; $find++; } elsif($in{'item3'} eq @T[2]) { @FIND[$find] = $TEST[$d]; $find++; } } } }
- 上記のコードは、csvデータの列に%で区切られた項目を処理するためのものです。具体的には、指定された項目値に基づいてデータを検索し、該当するデータを配列に格納しています。項目値は複数の条件で絞り込むことも可能です。ただし、項目値に含まれる%記号は特別な意味を持つため、そのままでは処理できません。split関数を使用して、%記号で項目値を分割しています。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
#1で述べたように %in の状態、具体的には $in{item2}と $in{item3}の値によって 誤カウントするバグがあります。 %inの情報を提示していただけませんでしたので、 勝手ながらスクリプトをちょっといじって確認してみました。 use strict; my @TEST = <DATA>; my %in = qw(item aaa); my @FIND; chomp @TEST; sub find_sub { my $find = 0; for (my $d = 0 ; $d < @TEST ; ++$d) { my @ITEM = split q{,}, $TEST[$d]; my @T = split q{%}, $ITEM[2]; #csvデータ内項目%区切り if ($in{'item'} eq $T[0]) { #@T[0]にaaaが入ります if (($in{'item2'} eq "") or ($in{'item2'} eq "全て")) { warn "condition 1 is true"; $FIND[$find] = $TEST[$d]; $find++; } elsif ($in{'item2'} eq $T[2]) { warn "condition 2 is true"; $FIND[$find] = $TEST[$d]; $find++; } if($in{'item2'} eq $T[1]) { if(($in{'item3'} eq "") or ($in{'item3'} eq "全て")) { warn "condition 3 is true"; $FIND[$find] = $TEST[$d]; $find++; } elsif ($in{'item3'} eq $T[2]) { warn "condition 4 is true"; $FIND[$find] = $TEST[$d]; $find++; } } } } $find; } foreach my $item (qw(aaa bbb ccc ddd)) { warn "search for $item...\n"; if ($item eq 'aaa') { $in{'item2'} = ''; } else { $in{'item2'} = $item; } my $f = find_sub(); warn "$f found\n"; } __END__ ,,aaa%bbb%ccc ,,aaa%bbb%ddd ,,aaa 実行結果は以下の通り: search for aaa... condition 1 is true at bug.pl line 19, <DATA> line 3. condition 1 is true at bug.pl line 19, <DATA> line 3. condition 1 is true at bug.pl line 19, <DATA> line 3. condition 3 is true at bug.pl line 30, <DATA> line 3. 4 found search for bbb... condition 3 is true at bug.pl line 30, <DATA> line 3. condition 3 is true at bug.pl line 30, <DATA> line 3. 2 found search for ccc... condition 2 is true at bug.pl line 24, <DATA> line 3. 1 found search for ddd... condition 2 is true at bug.pl line 24, <DATA> line 3. 1 found aaaの検索のときに、19行目付近のブロックと30行目付近のブロックで 合わせて2回カウントしていますので、 答えも違うというわけです。 どういう条件設定なのかわかりませんので修正方法は 提示できません。
その他の回答 (1)
- sakusaker7
- ベストアンサー率62% (800/1280)
>1行目:aaa%bbb%ccc >2行目:aaa&bbb%ddd >3行目:aaa%bbb > >csvデータ内にはaaaは3個だけですが下記コードで実行すると >aaaが6個と計算されます。bbb、ccc、dddの個数は正確に計算されます。 提示のデータだとaaaは2個ではないですか? aaa&bbb は &で分割する手順がないので一かたまりで扱われると思うのですが。 > (@ITEM) = split(/\,/, $TEST[$d]); > @T = split(/\%/, @ITEMD[2]); #csvデータ内項目%区切り この2行と質問の先頭にある3行とでフォーマットのつじつまが合っていません。 ','による split が行われたものであるなら納得できるのですが。 見た限りでは %in の値の状態によっては二重にカウントする可能性がありますね。 本当に誤カウントしたときのデータを提示していただけませんか?
補足
すみません。記載ミスです。 2行目:aaa%bbb%ddd 全て%区切りです。 データパターンでわかったことですがaaa%bbbのようにaaaの後に項目がつながっているデータは正確に計算されますがaaaのみのデータは倍計算されます。 倍計算されるデータ↓ 1行目:aaa%bbb%ccc 2行目:aaa%bbb%ccc 3行目:aaa 上記の場合、aaaは3個ですが、aaaのみのデータがあるため aaaは4個と計算されます。 何卒、ご教授ください。