• ベストアンサー

CSVから値の割り出し

CSVファイルの1行目を渡された引数から値を割り出し、配列(@x)に 格納して、2行目以降も1行目で評価された要素と同じ位置の要素を 別配列(@y,@z)に入れて、渡された複数の引数をもとに下記のように 評価したいのですが可能ですか? 例)CSVファイル:1レコード目:1,1,1,2,2,2,3,3,3        2レコード目:1,2,3,4,5,6,7,8,9        3レコード目:A,B,C,D,E,F,G,H,I 引数:2,3,1なら 結果:2,6,D   @x=2,2,2 @y=4,5,6 @z=D,E,F

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

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#2の補足を読んでちょっとしたサンプルを作ってみました。 ---------------------------------------------------------------- #make_select は、 #make_select(検索値, 配列) の様に呼び出して、 #マッチした位置のデータを選択するような関数を返す sub make_select ($@){ my ($para, @data) = @_; my @pos=(); my $i,$len=@data; for($i=0;$i<$len;$i++){ push @pos, $i if $data[$i] eq $para; } return sub { my ($data, $select) = @_; foreach(@pos){ push @$select, $data->[$_]; } }; } #元のデータ my @x = (1,1,1,2,2,2,3,3,3); my @y = (1,2,3,4,5,6,7,8,9); my @z = qw(A B C D E F G H I); #セレクトする関数を作る my $select=make_select(1, @x); #格納先配列 my @xx=(); my @yy=(); my @zz=(); #&$select(元データの配列のリファレンス, 格納先配列のリファレンス) &$select(\@x, \@xx); &$select(\@y, \@yy); &$select(\@z, \@zz); #結果の表示 print join(",", @xx) . "\n"; print join(",", @yy) . "\n"; print join(",", @zz) . "\n";

polalis
質問者

お礼

BLUEPIXY様、 仕事が遅くなり返事が遅れてスミマセン。 私のつたない説明で、こんなサンプルまで作って頂いて 本当にありがとうございました。 私もPerlを勉強中の身なので、サンプルコードを良く噛み 砕いて勉強させていただきます。 自分で調べても、わからないことや疑問点が沸いてきたら またBLUEPIXY様にお聞きするかもしれませんが、そのときは どうぞよろしくお願い致します。

その他の回答 (2)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#1の方と同じような質問になりますが、#1の補足を読んでも意味がわかりません。 引数:2,3,1の意味は、 2の要素の始まる位置から3つの要素で1を除くとか 2の要素の始まる位置から3の要素の始まる1つ前の位置までの要素 とか そういう(つまり渡されるパラメータの)意味が知りたいのですが

polalis
質問者

お礼

やりたいことが説明しきれておらず、理解が苦しいですよね? すみません…。 スクリプト自体は、サブルーチンとして使用するのですが、 メインのスクリプトはアンケートになっていて、すべての設問を終えるとパラメータ(引数)がPOSTされます。 例)1,3,2,3,2…(分解後) パラメータの意味は、「Q1」に対して「1」を答えたみたいな感じです。 それに対して、このスクリプトでCSVファイルから画面IDのような ものを算出しようと思っています。(行:設問数,列:戻り値) 質問1 まずパラメータをもとにCSVファイルの1行目から、ヒットされた値の要素を全て切り出して配列に格納したいのですが可能ですか? 質問2 上記1行目の評価から、2行目以降も同じ位置の要素を別の配列に格納したいのですが、可能ですか? ※@x…CSVファイルの1行目、@y…2行目、@z…3行目の値が入っています。 例) @xは「1,1,1,1,2,2,2,2,3,3,3,3」でパラメータが「1」なら「1,1,1,1」の部分(@x[0]..[3])を抜き出して配列@xxへ格納。 そのまま渡された値「1」を返す。 (パラメータが「2」なら「2,2,2,2」部分(@x[4]..[7])を抜き出す。) 2行目以降は、評価せずに@y[0]..[3]または@x[4]..[7]の要素を@yyに格納する。 それから評価して、第2パラメータが「3」なら、@yyの3番目の要素(@yy[2])を返す。 結果的には、1行目で要素の範囲を絞って2行目以降から、絞った列で値を返したいということなんですが、ご教授願えませんか?

noname#96023
noname#96023
回答No.1

たいした事していないのでできると思いますが アルゴリズムが理解できないです >1行目を渡された引数から値を割り出し、配列(@x)に 格納して これって何をやっているの?

polalis
質問者

お礼

説明が下手ですみません。 アンケートの結果IDをCSVから割り出そうとしています。 ローカルのテストでDOS窓のperlコマンドからパラメータを5~6個程 引き渡して、CSVファイルの該当箇所を割り出そうと思っています。

関連するQ&A

  • CSVから値の割り出し3

    Perl初心者です。 締め切った要件にて、またお聞きするのは回答者様達に 大変失礼だと思ったのですが、どうしても解らなかった為 また教えてください。 「CSVからの値の割り出し2」にて、コードまで送って頂いた のですが、私の動作確認不足のために教えていただいた方に 不快な思いをさせるのは、大変心苦しい限りです。 申し訳ありません。。。 コードの概要は、渡されたパラメータを元にCSVファイルの カラムを絞っていって、評価した値を最後のレコードにて 割出す…というスクリプトです。 ※お手数ですが「CSVからの値の割り出し2」を参照して下さい。 CSVファイルの一番右の縦列をパラメータに指定すると何故だか 値が割出せません。ほかは問題ないのですが。 $data[x]->[y]で確認すると、値は存在するのにマッチして くれません。 これは、どうすれば解消できますか?教えてください。 それと、Open関数にて「die」が選択されたときにlogに出力 するというのをサブルーチンで、共通関数みたいな形にした いのですがどうすればいいのでしょう? よろしくお願い致します。

    • ベストアンサー
    • Perl
  • CSVから値の割り出し2

    お世話になります、Perl初心者です。 先日、同じような投稿を投げているのですが、完全に仕様を勘違い していて、また助言をして頂きたく投稿しました。 サンプルを送ってくれたBLUEPIXY様、すみません。 まずやりたい事は、アンケートのフォームからPOSTされた データをCSVファイルに突き合わせて、値を割り出すという ことなんですが… <CSVファイルの例> 1,1,1,2,2,2,3,3,3 1,2,3,1,2,3,1,2,3 1:3,1:3,1:3,3,1:2,3,1,2:3,1,2:3 "1,3","1,3",2,1,"2,3",1,"1,3",2,2 "A","B","C","-","D","-","E","F","G" 行は、設問の数だと想定して下さい。上からQ1,Q2…のような 感じです。英字の部分は結果(出力)になります。 ◆1:3は、1,2,3のどの値が入ってもというのを意味します。 ◆"1,3"は、1か3のどちらかという意味です。 ◆"-"はNullです。 渡されるパラメータは数字の1~3まで、設問数分一気に送られて きます。例)1,2,1,2,3… 渡されたパラメータを元に、上から値(範囲)を絞っていって 結果を返します(英字) 例) パラメータ「2,2,1,3」(1行目,2行目…)  結果「D」 これは、1行目をパラメータ「2」に対してマッチさせて 「2,2,2」の範囲を得ます。2つ目も「2」なので、1行目 の範囲の中から、ヒットする数値を割り出します。 それ以降も同じ要領で、絞っていき結果を出します(英字) このサンプルCSVだと、結果は2行目で決まってしまうの ですが、本来はもっと行が多いです。 恥ずかしい話なんですが、grepをしたらいいのか、 posで位置を得たらいいのか、lengthでバイト数を測れば いいのか、いい方法が思いつきません。 カンマやコロンでの処理が出来るのかどうかも解りません。 どうか、ご教授願えないでしょうか?

    • ベストアンサー
    • Perl
  • VBAでCSV同士のマージ

    先日、CSVの読み込みについて質問させていただきましたが、マージについての質問に変更して改めて質問させてください。 XとYというCSVファイルがあり、Yの内容とXの内容を合わせた結果を新しいシートに貼り付けるVBのコードを作成しています。 XとYの配列にCSVの内容をそのまま入れ、以下のようなマッチング方法でXの配列にYの内容も入れました。 'マッチング If X(0) = Y(0) Then 'IDが一致した場合 For i = 1 To UBound(Y)  'IDを除いたYファイルの終わりまで Index = Index + 1 '列番号追加 ReDim Preserve X(Index) '上記で追加した番号をXの配列に追加 X(Index) = Y(i) '追加した配列にYの要素を入れる Next i End If ここで、新規シートに内容を表示するのですが、ここの結果がどうもおかしくて、Yの内容が反映された行は最後の行のみになってしまいます。 例として X.csv ID,名前 2001,TARO 2002,JIRO 2003,SABURO Y.csv ID,出席 2001,○ 2002,X 2003,○ のようなものがあったとして、マッチング結果が ID,名前 2001,TARO 2002,JIRO 2003,SABURO,○ と言った感じに最後のみ反映されています。 どなたか解決方法ご存知のかたよろしくお願いします。

  • SQL*LoaderでCSVから指定した列のみインポートしたい。

    SQL*Loaderを用いてOracleのテーブルにデータを格納 しようと思っています。 格納するデータはカンマ区切りのCSVファイルです。 入力CSVファイルは他テーブル用のファイルなので、 ローダーで落とし込むテーブルとは列数が異なります。 ですので、「CSVの5列目の値をテーブルのAA_NOというフィールドに 格納する。ということが可能なのでしょうか?」 CSVファイルのある行が a,b,c,d,e,f というデータの場合、テーブルには a,e,f とインポートしたいのです。 よろしくお願いします。

  • CSVファイルを多次元配列に格納する

    CSVファイルをopenCSVを読み込んでその行と列の要素数の多次元配列を作りその配列にデータを格納したいです。 しかし、データが格納できません。2回目の格納するためにwhileから何かおかしいのではないかと思っています。 なにかわかる方、アドバイスが欲しいです。 public class ReadCSV { public static void main(String[] args){ try{ CSVReader reader = new CSVReader( new FileReader("/home/masa/Desktop/WameiSample.csv")); //配列の宣言 String[] nextLine; //データを配列に入れる要素数を見る int j = 0; nextLine = reader.readNext(); int k = nextLine.length; System.out.println("列数[i]"+k); System.out.println("nextLine"+nextLine); while((nextLine = reader.readNext()) != null){ for (int i=0; i<nextLine.length; i++){ //System.out.print(nextLine[i] + "|" + i + "|"); } //System.out.println(); j++; } System.out.println("行数[j]"+j); //記憶する配列 String[][] Wamei = new String[k][j]; System.out.println("きてるよ"); //データを配列に格納していく int x = 0; while((nextLine = reader.readNext()) != null){ System.out.println("きてるよ");  <---こっから、表示してくれない. for (int y=0; y<nextLine.length; y++){ Wamei[x][y] = nextLine[y]; //多次元配列の要素を表示する System.out.print(Wamei[x][y]+"Wamei"+x+y); } System.out.println(); x++; } } catch (IOException e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • VBScriptでCSVファイルを読み出したい

    現在VBScriptでCSVファイルを1行ずつ読み取って、2次元配列に格納するプログラムを作成しています。 CSVファイルの中身は、サンプルで shop,price,sales 001,500,700 003,1200,90 024,,18 という並びになっています。 実データは300件くらいです。 1行目のヘッダーを読み飛ばし、2行目のデータから1行ずつ読取、","でsplitを用いてまず1次配列に格納しています。 1次元配列のarrLine(0)=001、(1)=500、(2)=700と入ったデータを 2次元配列arrshopに順次保存?したいのです。 ---------------------------------------------- dim strLine '1行ずつ読込んだデータを持つ dim ntLineNum '行数のカウント dim arrLine '","で区切った要素を持つ一次元配列 dim arrshop '一次元配列になった要素を2次元配列として格納 Do until .AtEndOfStream   strLine = .ReadLine   if 0<>strComp("",Trim(strLine)) then ntLineNum = intLineNum + 1   end if   arrLine = split(strLine , ",")   arrshop = Array(arrLines,i) i = i + 1 loop ----------------------------------------- msgbox arrshop(2)(0) と指定すると「003」出るようにしたいです。 Array関数が上手くないような気もします・・・。 どなたかご教授お願いします(>_<。)

  • csvファイルの横方向への改行について

    ある2次元配列があったとして, セルをちゃんと改行しつつcsvファイルに 書き込みをしようとしてるのですが 英字の方へ改行をする方法がわかりません. int a[4][4] ;   :   : FILE *file; file = fopen("condidate.csv","w"); for(int x = 0; x < 5 ; x++) { for(int y = 0; y < 5; y++) { fprintf(file,"%d\n", a[x][y]); } //改行←ここがわからない } fclose(file); csvファイル 1つの配列が1つのセルに入っている状態 ↓  A B C D _ _ _ _ 1 |1 1 1 1 2 |1 1 1 1 3 |1 1 1 1 4 |1 1 1 1 上記のものを作りたいです. よろしくお願いいたします.

  • openでcsvを開いた時

    openでcsvを開き配列に格納したまでは良いのですが、 何行(いくつの配列)格納したかの最大値を知りたいのですが、何か関数はありますか?

    • ベストアンサー
    • CGI
  • 複数のcsvファイルをマクロ(VBA)で取り込みたい

    複数のcsvファイルをマクロ(VBA)で取り込みたい csvファイルの中身が、 20090507 120508 osaka 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 b1,b2,b3,・・・・・,b10 c1,c2,c3,・・・・・,c10 や 20090507 132529 hokkaido 項目1,項目2,項目3,・・・・・,項目10 d1,d2,d3,・・・・・,d10 e1,e2,e3,・・・・・,e10 f1,f2,f3,・・・・・,f10 となっているcsvファイルが特定のフォルダの中に100以上あります。 このcsvふぁいるの5行目だけをaccessに書き込んでテーブルに追加していきたいと思っています。 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 d1,d2,d3,・・・・・,d10 このようなテーブルができればいいのですが・・・ csvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する)→次のcsvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する) この流れでいいと思うのですが方法が分かりません。 丸投げですがよろしくお願いします。

  • Fortran99で複数ファイルの読み込み

    Fortran99で有限要素法の解析プログラムを作成しています。 要素番号と節点番号、各節点の座標を三次元の配列にまとめて格納したく、 複数のcsvファイルを相互に参照しながら配列に読み込みたいと思っていますが、 その方法が分かりません。 具体的には、一つ目のファイル(ex1.csv)の中身が、 1 1 2 10 11 20 21 30 31 2 2 3 11 12 21 22 31 32 3 3 4 12 13 22 23 32 33 ........ と配列になっており、1列目が要素番号、2~8列目が節点番号としています。 二つ目のファイル(ex2.csv)の中身が、 1 0 0 0 2 5 0 0 3 10 0 0 4 15 0 0 5 20 0 0 ..... となっており、1列目が節点番号、2~4列目がそれぞれ、x, y, z座標となっています。 一つ目のファイルは、 open(10, file = 'ex1.csv', status = 'old', action = 'read', position = 'rewind') do ELEM = 1, MAXELEM read(10, *) (ELEMDATA(ELEM, m, 1), m = 1, 8) enddo close(10) と書き、全ての要素と節点番号を三次元配列の一、二次元目に読み込みました。 次に、ex1.csvの節点番号(2~8列目)の番号を読み取り、その番号をex2.csvの1列目 から探し出して、配列の三次元目に格納したいと思っています。 宜しくお願い致します。

専門家に質問してみよう