質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

3回答

1866閲覧

csvのデータを2次元配列に格納したい

退会済みユーザー

退会済みユーザー

総合スコア0

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2017/07/09 14:52

###前提・実現したいこと
data2.txtというテキストファイルがあります。

"aaa1","bbb1","ccc1","ddd1"
"aaa2","bbb2","ccc2","ddd2"
"aaa3","bbb3","ccc3","ddd3"
"aaa4","bbb4","ccc4","ddd4"

data2.txtの""で囲った文字列を2次元配列の要素に格納したいです。
array[0][0] = "aaa1"
array[1][0] = "bbb1"
array[2][0] = "ccc1"
array[3][0] = "ddd1"
array[0][1] = "aaa2"
~
array[3][3] = "ddd4"

###ご依頼
上記の内容を実現できるソースコードを作成しました。
ソースコードは以下の通りです。
以下のソースコードよりスマートな記述内容がありましたらご教示頂けませんでしょうか。

perl

1open my $fh, "<", "data2.txt" or die $!; 2while (my $hairetsu = <$fh>) { 3 my @hairetsu = $hairetsu =~ /"[^,]*"/g; 4 my @hairetsu2 = (); 5 my $i = 0; 6 $hairetsu2[0][$i] = "@hairetsu[0]"; 7 $hairetsu2[1][$i] = "@hairetsu[1]"; 8 $hairetsu2[2][$i] = "@hairetsu[2]"; 9 $hairetsu2[3][$i] = "@hairetsu[3]"; 10 print("$hairetsu2[0][$i]\n"); 11 print("$hairetsu2[1][$i]\n"); 12 print("$hairetsu2[2][$i]\n"); 13 print("$hairetsu2[3][$i]\n"); 14 $i = $i++; 15} 16close $fh;

###出力結果

Scalar value @hairetsu[0] better written as $hairetsu[0] at C:\xampp\htdocs\test\test2.pl line 6. Scalar value @hairetsu[1] better written as $hairetsu[1] at C:\xampp\htdocs\test\test2.pl line 7. Scalar value @hairetsu[2] better written as $hairetsu[2] at C:\xampp\htdocs\test\test2.pl line 8. Scalar value @hairetsu[3] better written as $hairetsu[3] at C:\xampp\htdocs\test\test2.pl line 9. "aaa1" "bbb1" "ccc1" "ddd1" "aaa2" "bbb2" "ccc2" "ddd2" "aaa3" "bbb3" "ccc3" "ddd3" "aaa4" "bbb4" "ccc4" "ddd4"

###補足情報(言語/FW/ツール等のバージョンなど)
・Active Perl v5.24.1
・Windows 10 Home
・Sublime Text 2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

普通に記載するなら、A.Ichiさんの解答で十分かと。
コードゴルフ的なスマートさを求めるなら

open my $fh, '<', 'data2.txt' or die $! ; my @data = map { chomp ; [ split /,/ ]} <$fh> ; close $fh ;

で、ダブルコーテーション込みで配列化されます。

投稿2017/07/10 14:52

bunzaemon

総合スコア118

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

スマートな記述内容ではないかもしれませんが

perl

1open (IN, "data2.txt") or die "$!"; 2my @data; 3while(<IN>) { 4 chomp($_); 5 $_=~ s/"//g; 6 my @buf = split(/,/, $_); 7 push @data, [ @buf ]; 8}

投稿2017/07/09 23:03

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「よりスマート」とか以前に、このスクリプトは意図通りには機能しないはずですね。

まず、
致命的なのは、ループの中で

perl

1my @hairetsu2;

としていること。
ループ回るたびに@hairetsu2はリセットされてしまいます。これでは最終行の内容しか保存されません。
そもそもループの外でこの配列を参照できないので、このコードは実質的に意味をなしません。

次に、

perl

1$hairetsu2[0][$i] = "@hairetsu[0]";

@hairetsuの中の「要素」を参照するときは、$hairetsu[0]です。perlインタプリタは一応処理はしてくれますが、Scalar value @hairetsu[0] better written ... と文句を言っています。

さらに、

perl

1$i = $i++;

$iは永遠に0のままです。$iを+1する「前」の値を$iに代入してしまうから。
単純に

perl

1$i++;

とすべきです。これに限らず、インクリメンタル・デクリメンタル演算子を他の演算子と混ぜて使うことは全くおすすめしません。計算の優先順位をきちんと把握しておかないと間違いの元です。少なくとも初級者のうちは、たかが数文字をケチることより、解りやすく間違いにくいコーディングを心がけるべきです。

さて、スクリプトの途中でprintを挟んで動作を確認するのは良い考えだったのですが、最終結果のチェックが出来ていないため数々の間違いを見逃す結果となっています。こういうとき、スクリプトの先頭で

perl

1use Data::Dumper;

と宣言しておくと、スクリプトの最後で

perl

1print Dumper @hairetsu2;

とすることで中身を直接確かめることが出来ます。

投稿2017/07/09 16:55

編集2017/07/09 16:57
KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問