- ベストアンサー
無名配列からハッシュを作りたいのですが・・・
$VAR1 = [ 'No', 'a', 'i', 'u', 'e', 'o', ]; #VAR1と同じ数の<>区切りの下記のようなデータを読み込み配列に代入 --List----------------------- 1<>あ<>い<>う<>え<>お<> ------------------------- foreach(0..$#List){ @Array=split(/<>/,$List[$_]); } 最終的なイメージは print "$a{No}"; >1 print "$a{a}"; >a となるよう、上記VAR1の無名配列の値をキーに、読み込んだ<>区切りのデータを関連付けて表示させるようにしたいのです。 foreach my$var(@$VAR1){ ...ここをどうすれば配列の値をハッシュのキーとして作成出来るのか頭を悩ませてます。 } 先輩方のお知恵をお借りできませんでしょうか。 宜しくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
No.2の補足に書かれているコードをそのままコピペして試してみましたが、 正常に動作しました。 $VAR1や@Listにうまく値が入っていない可能性があると思います。 データがファイルに保存されているのなら、各項目の意味($VAR1相当)を最初 の行に書き、その後にデータを羅列していくのはどうでしょうか? 以下、それを処理するサンプルコードです。 my @labels = split /<>|\n/, <DATA>; my @data; while (my $line = <DATA>) { chomp $line; my %hash; @hash{@labels} = split /<>/, $line; push @data, \%hash; } print $data[0]{e}, "\n"; #=> え print $data[1]{u}, "\n"; #=> く print $data[2]{o}, "\n"; #=> そ __DATA__ No<>a<>i<>u<>e<>o 1<>あ<>い<>う<>え<>お 2<>か<>き<>く<>け<>こ 3<>さ<>し<>す<>せ<>そ
その他の回答 (4)
- ryu_chan
- ベストアンサー率37% (69/186)
No.3のTacosanさんがおっしゃてるように、@Listの内容が以下のような場合 @List = ( '1<>あ<>い<>う<>え<>お<>', '2<>か<>き<>く<>け<>こ<>', '3<>さ<>し<>す<>せ<>そ<>', ); foreach(0..$#List){ @Array=split(/<>/,$List[$_]); } の処理だと、@Arrayには、@Listの最後の文字列 @Array → ('3', 'さ', 'し', 'す', 'せ', 'そ') しか入りません。 もしかしてこういう意図でしょうか? foreach(0..$#List){ @Array=split(/<>/,$List[$_]); @a{@$VAR1} = @Array; -- 以下、%aを使った処理が続く -- } そうでなければ、こういうデータ構造はいかかでしょうか? もちろん全体的な設計が分からないので的外れな提案かもしれませんが。 my $VAR1 = [ 'No', 'a', 'i', 'u', 'e', 'o', ]; my @List = ( '1<>あ<>い<>う<>え<>お<>', '2<>か<>き<>く<>け<>こ<>', '3<>さ<>し<>す<>せ<>そ<>', ); my @data; foreach (0..$#List) { @{$data[$_]}{@$VAR1} = split(/<>/, $List[$_]); } print $data[0]{e}, "\n"; #=> え print $data[1]{u}, "\n"; #=> く print $data[2]{o}, "\n"; #=> そ
お礼
ご配慮兼ねたお気遣いや配列のハッシュ若しくはハッシュの配列の作成に関する事例までご掲示頂きありがとうございます。目的の値を表示出来た際は気持ちいいですね。 No2:ryu_chanさんへの回答にもあるのですが、 大前提として、 Listの中身は1行のファイルだったのです。最初に明示しておかなくてすいませんでした。 この参照のやり方がわかると、保存ファイルを個別にするのではなくて、一つのファイルに保存すれば良いなぁ・・と思えてきました。 仕様変更するのかどうするか・・って悩み所です^^; 有難う御座いました。
- Tacosan
- ベストアンサー率23% (3656/15482)
や, #2 で指摘しているのは foreach(0..$#List){ @Array=split(/<>/,$List[$_]); } って実は @Array = split /<>/, $List[-1]; と同じことではないのか, ってことじゃないでしょうか. 実際, それより前のものは split した結果を上書きしちゃってますよね. 無名配列かどうかとは関係ないと思います.
お礼
そうゆうお気遣いからだったんですか・・・ フォロー有難う御座います。
- ryu_chan
- ベストアンサー率37% (69/186)
以下のようにハッシュスライスを使うのはいかがでしょうか? @a{@$VAR1} = @Array; 疑問というか、以下の処理がちょっと謎です。 foreach(0..$#List){ @Array=split(/<>/,$List[$_]); } こう↓したいわけではないでしょうか? foreach(0..$#List){ push @Array, [ split(/<>/,$List[$_]) ]; }
お礼
ご教授頂きありがとうございます。 foreach(0..$#List){ push @Array, [ split(/<>/,$List[$_]) ]; } についてですが、@Listが無名配列の場合は、そのようにすればよいのかな・・と思うのですけど、通常の配列の場合ですと @Array=split(/<>/,$List[$_]); で代入されるようです。
補足
ハッシュのスライスというのがあるんですね。有難う御座います。 @a{@$VAR1} = @Array; の@a{}となっているのに疑問を持ちつつ、勝手に配列のスライスと勘違いして調べてましたw で、私の方で表示テストを行ってみたのですが、@a{@$VAR1}の中身の確認が出来ませんでした。 後、大前提としてですが、 --List----------------------- 1<>あ<>い<>う<>え<>お<> ------------------------- の中身は1行のみでした。すいません foreach(0..$#List){ push @Array, [ split(/<>/,$List[$_]) ]; } のご教授有難う御座います。 で、それを前提に my@Array; my%a; foreach(0..$#List){ @Array=split(/<>/,$List[$_]); } @a{@$VAR1} = @Array; print "■テスト表示<br><br>"; print "\@a=@a<br>"; print "\@$a=@$a<br>"; print "\$a[0]=$a[0]<br>"; print "\$a[0]->{BCorpName}=$a[0]->{a}<br>"; print "\$a->[0]->{a}=$a->[0]->{a}<br>"; print "\$a[0]{a}=$a[0]{a}<br>"; print "\$a{a}=$a{a}<br>"; とテスト表示してみたのですが、中身が何も表示されず use Data::Dumper; open(F,"> Datadump_a.txt") ; # 保存するファイルを開く print F Dumper(\%a,*a); # 連想配列の内容をファイルに書き出す #print F Dumper(\@a); # 連想配列の内容をファイルに書き出す #print F Data::Dumper->Dump( [ \%a ] , [ '*a' ] ); close(F); として内容を確認してみたのですが、中身が何も入ってないようです。 今回の件で私自身ハッシュや配列のスライスについて、もう少し勉強が必要な事を痛感させられました。 お手数ですが、上記の件についてもし何かご助言いただけます様でしたら幸いです。 宜しくお願い致します。
- Tacosan
- ベストアンサー率23% (3656/15482)
Perl5 だとその形では無理なはず. %a = map { $VAR1->[$_] => $Array[$_] } 0 .. $#$VAR1; でできるか? Perl6 なら zip するところかな.
お礼
無事ご教授頂いた内容でばっちりOKでした。 ありがとうございます。 後、イメージ出来たため、下記のようにテストしてみたら下記のでも大丈夫でした。 $c=0; foreach my$var(@$VAR1){ print "\$var=$var<br>"; $a{$var}=$Array[$c]; $c++; } でも、大丈夫でした。 mapを使うと1行で可能になるとは、考えもしませんでした。 とても参考になりました!有難う御座います。
お礼
確認の方ありがとうございます。 私の方で先日から検証を行っていた際、途中から local $Data::Dumper::Varname = "$Test"; として、検証を行っていた関係で、途中から$VAR1を読み込めず空だったみたいです。お察しよいですね^^ Data::Dumperがかなり便利と言っても、それに拘る必要はないんですね というより、元を正せば同じ配列なのか・・・と気が付きました。 特殊リテラルを使って分かりやすく解説頂きありがとうございます。 1行目の my @labels = split /<>|\n/, <DATA>; 部分とか、わざわざファイルをテスト用に作ったりする必要がなく__DATA__部分以降でテスト確認が出来る技術は凄いですね。 恐れ入ります。 色々ご教授頂き有難う御座いました