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

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

ただいまの
回答率

90.51%

  • 正規表現

    924questions

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

  • Perl

    495questions

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

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

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 2,818

kohenro19

score 43

前提・実現したいこと

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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

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 ;

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • 正規表現

    924questions

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

  • Perl

    495questions

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