csvのデータを2次元配列に格納したい
受付中
回答 3
投稿
- 評価
- クリップ 0
- VIEW 5,397
前提・実現したいこと
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"
ご依頼
上記の内容を実現できるソースコードを作成しました。
ソースコードは以下の通りです。
以下のソースコードよりスマートな記述内容がありましたらご教示頂けませんでしょうか。
open my $fh, "<", "data2.txt" or die $!;
while (my $hairetsu = <$fh>) {
my @hairetsu = $hairetsu =~ /"[^,]*"/g;
my @hairetsu2 = ();
my $i = 0;
$hairetsu2[0][$i] = "@hairetsu[0]";
$hairetsu2[1][$i] = "@hairetsu[1]";
$hairetsu2[2][$i] = "@hairetsu[2]";
$hairetsu2[3][$i] = "@hairetsu[3]";
print("$hairetsu2[0][$i]\n");
print("$hairetsu2[1][$i]\n");
print("$hairetsu2[2][$i]\n");
print("$hairetsu2[3][$i]\n");
$i = $i++;
}
close $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
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
「よりスマート」とか以前に、このスクリプトは意図通りには機能しないはずですね。
まず、
致命的なのは、ループの中で
my @hairetsu2;
としていること。
ループ回るたびに@hairetsu2はリセットされてしまいます。これでは最終行の内容しか保存されません。
そもそもループの外でこの配列を参照できないので、このコードは実質的に意味をなしません。
次に、
$hairetsu2[0][$i] = "@hairetsu[0]";
@hairetsuの中の「要素」を参照するときは、$hairetsu[0]です。perlインタプリタは一応処理はしてくれますが、Scalar value @hairetsu[0] better written ... と文句を言っています。
さらに、
$i = $i++;
$iは永遠に0のままです。$iを+1する「前」の値を$iに代入してしまうから。
単純に
$i++;
とすべきです。これに限らず、インクリメンタル・デクリメンタル演算子を他の演算子と混ぜて使うことは全くおすすめしません。計算の優先順位をきちんと把握しておかないと間違いの元です。少なくとも初級者のうちは、たかが数文字をケチることより、解りやすく間違いにくいコーディングを心がけるべきです。
さて、スクリプトの途中でprintを挟んで動作を確認するのは良い考えだったのですが、最終結果のチェックが出来ていないため数々の間違いを見逃す結果となっています。こういうとき、スクリプトの先頭で
use Data::Dumper;
と宣言しておくと、スクリプトの最後で
print Dumper @hairetsu2;
とすることで中身を直接確かめることが出来ます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
スマートな記述内容ではないかもしれませんが
open (IN, "data2.txt") or die "$!";
my @data;
while(<IN>) {
chomp($_);
$_=~ s/"//g;
my @buf = split(/,/, $_);
push @data, [ @buf ];
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
普通に記載するなら、A.Ichiさんの解答で十分かと。
コードゴルフ的なスマートさを求めるなら
open my $fh, '<', 'data2.txt' or die $! ;
my @data = map { chomp ; [ split /,/ ]} <$fh> ;
close $fh ;
で、ダブルコーテーション込みで配列化されます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.18%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる