• ベストアンサー

ハッシュの配列を作ることは可能でしょうか?

次のようなファイルがある場合、%hash1と%hash2を同じ配列として扱いたいと思っています。 例えば、hash[0]{A}とアクセスすれば'01'、hash[1]{B}とアクセスすれば'002'となるようにしたいと思っています。ご教授ください。 -------------------- A B C 01 001 0001 02 002 0002 %hash1 = {'A'=>'01', 'B'=>'001', 'C'=>'0001'}; %hash2 = {'A'=>'02', 'B'=>'002', 'C'=>'0002'};

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

  • ベストアンサー
  • Dpop
  • ベストアンサー率51% (279/544)
回答No.2

#1 です。答えです。(なんとなく。) #/usr/local/bin/perl @data = ( {'A'=>'01', 'B'=>'001', 'C'=>'0001'}, {'A'=>'02', 'B'=>'002', 'C'=>'0002'}); foreach $j (sort keys %{$data[0]}) { print $j. ' '; } print "\n", '-'x 10, "\n"; for $i (0 .. scalar(@data)-1) { foreach $j (sort keys %{$data[$i]}) { print $data[$i]{$j}. ' '; } print "\n"; } こんな感じで良いかな。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

ファイルの1行目が項目名で、各項目は空白(タブ)で区切られている、という前提で。 sub read_data {   my (@key, @data);   local $_;   open FH, shift or die $!;   chomp($_ = <FH>);   # キー取り出し   @key = split /\s+/;   while (<FH>) {      # データ取り出し     chomp;     my %d; @d{@key} = split /\s+/;     push @data, \%d;   }   close FH;   return @data; } という関数を作成すると、 @hash = read_data("ファイル名"); print $hash[0]{A};   # 01 と表示される。 print $hash[1]{B};   # 002 と表示される。 のように使えます。 ※スクリプトの字下げに全角スペースを使っているので、コピーする場合はタブなどに置き換えてご利用ください。

全文を見る
すると、全ての回答が全文表示されます。
  • Dpop
  • ベストアンサー率51% (279/544)
回答No.1

参考になるソースを示しますので、読んで見てください。 # ハッシュの配列を静的に作る %c = ( A => [ qw(aa ab ac ad ae) ], B => [ qw(ba bb bc bd be) ], C => [ qw(ca cb cc cd ce) ] ); # 静的に作ったハッシュの配列を取り出してみる foreach $i (sort keys %c) { for $j (0 .. scalar(@{$c{$i}})-1) { print '$c{'. $i. '}['. $j. ']='. $c{$i}[$j]. ' '; } print "\n"; } print "\n"; # ハッシュの配列を動的に作る %g = (); open(IN, 'in.data') || die "open error"; while(<IN>) { chop; my(@w); @w = split(/ /); $g{uc(substr($_, 0, 1))} = \@w; } close(IN); # 動的に作ったハッシュの配列を取り出してみる foreach $i (sort keys %g) { for $j (0 .. scalar(@{$g{$i}})-1) { print '$g{'. $i. '}['. $j. ']='. $g{$i}[$j]. ' '; } print "\n"; } print "\n"; 動的に作る。の方は、 aa ab ac ad ae ba bb bc bd be ca cb cd ce cf こんなデータを読み込むようになっています。どちらの場合でも、 $g{A}[0]=aa $g{A}[1]=ab $g{A}[2]=ac $g{A}[3]=ad $g{A}[4]=ae $g{B}[0]=ba $g{B}[1]=bb $g{B}[2]=bc $g{B}[3]=bd $g{B}[4]=be $g{C}[0]=ca $g{C}[1]=cb $g{C}[2]=cd $g{C}[3]=ce $g{C}[4]=cf と言う結果が返ってきます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 二次元配列のハッシュ版の記述方法?

    二次元配列のハッシュ版を実現させたいのですが、 以下の記述で正しいでしょうか? 構文に疎いので教えてください。 #!/usr/bin/perl %HASH_TEST = ( 'あ'=>{'A'=>'1', 'B'=>'2', 'C'=>'3'}, 'い'=>{'A'=>'4', 'B'=>'5', 'C'=>'6'}, ); print $HASH_TEST{'い'}{'B'}; #=> 5が表示されます。 exit; __END__

    • ベストアンサー
    • Perl
  • ハッシュの中に格納された配列の要素数を得る方法

    予想配列のあるキーを配列とします。 %hash; @hash{'a'}=['aa','ab','ac']; 一方で普通の配列をスカラ変数として扱うと配列数を表します。 @array=(a,b,c,d,e); $num=@array; # $numは5になる。 それでは $num=@hash{'a}; あるいは  $num=@{hash{'a'}}; としたらどうなるのって ARRAY(0x2438c4) みたいになって、$numに@hash{'a'}の要素数は入りません。 予想配列の中に格納された配列の要素数を取り出す簡便な方法はないものでしょうか。 お手数をお掛けします。

    • ベストアンサー
    • Perl
  • 2次元ハッシュ または 2次元配列をソートしたい

    2次元ハッシュのソートをしたいです。 ハッシュは2つのキーを使用していて、 1つ目のキーは文字列、2つ目のキーは数字(0からの連番)です。 ハッシュの中身は文字列が入っています。 これを次のような表に見立てて、特定の列でソートしたいのです。 hash['a']['0'], hash['a']['1'], ..., hash['a']['50'], hash['q']['0'], hash['q']['1'], ..., hash['q']['50'], hash['c']['0'], hash['c']['1'], ..., hash['c']['50'], ... hash['d']['0'], hash['d']['1'], ..., hash['d']['50'], 例えば 6列目の値によってソートするということです。 以下のようにソートしようとしましたが、うまくいきません。 my @sorthash = sort { $a->[6] <=> $b->[6] } @hash; 何かヒントがあれば教えてください。

    • ベストアンサー
    • Perl
  • 配列とハッシュの配列の要素を比較してファイルに書き出したい

    配列Aとハッシュの配列Bがあり、配列の内容をファイルに書き出そうとしています。このとき、パターンマッチをして、Aにしかない場合はAのデータを、Bにしかない場合はBを、両方にある場合は、Aをファイルに出力しようとしています。 以下のようなループのまわし方をしようとして、試行錯誤しましたが、うまい方法を思いつくことができませんでした。 ご教授いただければうれしいです。 while (defined $A[$i]) {  my ($name, $pass);  $j=0;  while (($name, $pass) = each(%{$B[$j]})){    if ($A[$i] =~ /$name/) {    }    $j++;  } $i++; }

    • ベストアンサー
    • Perl
  • ハッシュ内の各値部分に配列を展開したい

    ハッシュ内の各値部分に配列を展開したいのですが、下記のようにしてみてるのですが、配列が全部展開されず、はまっております。宜しければご教授願えませんでしょうか。 use Data::Dumper; $Data::Dumper::Indent = 1; $dumpfile='dump.txt'; my @all = (aaa ,bbb); my @cate = qw(yyy zzz); my %hash; foreach my $a ( @all ) { foreach $b ( @cate ) { $hash{$a}[$b] = "$b"; } } open(F,"> $dumpfile") ; print F Dumper(\%hash); close(F); ■実行結果 $VAR1 = { 'bbb' => [ 'zzz' ], 'aaa' => [ 'zzz' ] }; ■イメージしている形 $VAR1 = { 'bbb' => ['yyy','zzz'], 'aaa' => ['yyy','zzz'], }; お手数ですが宜しくお願い致します。

    • ベストアンサー
    • Perl
  • 連想配列の操作方法について

    A,B,C,D,E 1,3,4,5,7 2,4,6,7,10 4,5,1,4,8 このようなコンマ区切りテキストファイルを読み込み、次のような配列をつくるには、どうのようにしたよいか悩んでいます。 ご教授ください。 [A,1,2,4],・・・,[E,7,10,8] (行と列を置き換えるように配列を作成したい)

    • ベストアンサー
    • Perl
  • 【初歩的質問】重複データがある時のハッシュへの代入について

    perl5.8です。すごくしようもない質問で申し訳ないのですが、次のようなファイルfile.txtの内容を、ハッシュ%hashに入れていくとします。 --- file.txtの中身 --- a,1 c,3 a,1 b,2 c,3 ----------------------- --- ソース(抜粋) ----- open(IN, "file.txt"); @data = <IN>; close(IN); %hash = (); foreach(@data){ chomp $_; @out = split(/,/, $_); $hash{$out[0]} = $out[1]; } ----------------------- 上記の結果は当然ながら、$hash{a}=1,$hash{c}=3,$hash{b}=2となるのですが、重複したデータを読み込んでハッシュに入れようとした時に、ワーニングなりエラーがなにも出なかったのがちょっと気持ち悪いです。重複したキーを読み込んだ時は、内部的には黙ってはじいてくれていると解釈してよいのでしょうか?そうだとすると、こういう書き方は、重複した行を排除するテクニックとなりえるのでしょうか?

  • 静的ハッシュの配列のキーに対応する値の数の多さ順で表示させたい

    ハッシュのキーに対応する値の数の多さ順で表示させたいと考え、下記の所まで試行錯誤しておりますが、どうにも思ったようにソートできずにおります。 #!/usr/bin/perl use strict; my(%a, $i, $j ,$allarray ,@keys ,@keys2 ,%hash ,%files ,$a_mumei_ref ,$key ,$value ,@value ,$x ,$files); # ハッシュの配列を静的に作る %a = ( '0' => [ qw(0) ], '1' => [ qw(1 1) ], '3' => [ qw(3 3 3) ], '7' => [ qw(7 7 7) ], '2' => [ qw(2) ], '4' => [ qw() ], '5' => [ qw() ], '6' => [ qw() ], '8' => [ qw(8 8) ], '9' => [ qw(9) ], ); @keys = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %a; #ハッシュのキーを数字順で表示 foreach (@keys){ print $_ ."\n"; } # 静的に作ったハッシュの配列を取り出してみる foreach $i (sort keys %a) { for ($j = 0; $j <= scalar(@{$a{$i}})-1; $j++) { print '$a{'. $i. '}['. $j. ']='. $a{$i}[$j]. ' '; } $allarray=scalar(@{$a{$i}})-1; print "No$i:kosuu:$allarray"; print "\n"; #配列の値の個数を調べその配列を作成 my($a_mumei) = $allarray; $a_mumei_ref = \$a_mumei; $files{"$i"}=($i,$a_mumei_ref); } #each関数で%filesの中身を表示 while ( ( $key , $value ) = each %files ){ print "key:$key value:$$value\n" ; } #試行錯誤 foreach $x (sort { $files{$b} <=> $files{$a} } keys %files){ print "$x => $files->{$x}\n"; } @keys2 = sort {$hash{$a} <=> $hash{$b}} keys %files; #@keys2 = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %files; #@keys2 = sort { $hash{$a} cmp $hash{$b} } keys %files; print "@keys2\n"; print "\n"; __END__; 私のイメージしておりますのは、ソートした結果がハッシュのキーに対応する値の数の多さ順で下記のように表示させたいのですが、 どのようにすれば可能でございますか、ご教授願えませんでしょうか key:3 value:2・・・この場合valueは配列の個数 key:7 value:2 key:8 value:1 key:1 value:1 key:9 value:0 key:2 value:0 key:0 value:0 key:6 value:-1 key:4 value:-1 key:5 value:-1

    • ベストアンサー
    • Perl
  • 配列について

    C言語についてです。 配列を次のように指定します。 a[3][3][3]={{ {1,7,6}, {6,9,2}, {3,1,1}, },{ {4,6,5}, {5,2,2}, {9,3,7}, },{ {2,6,8}, {2,2,4} {1,1,5}, }} b[3][3]={ {5,5,1}, {3,8,2}, {6,7,0}, } aの配列の中で、bの配列との差が1であるのが多い配列を表示するプログラムを教えてください。 ただし、 {1,7,6}, {6,9,2}, {3,1,1}, なら1、 {4,6,5}, {5,2,2}, {9,3,7}, なら2、 {2,6,8}, {2,2,4} {1,1,5}, なら3と表示する。

  • 2次元配列の使い方

    Access 2013 vba メイン画面に、2つのサブフォーム(共に帳票)があり 親→子→孫 となっています。 この時、親、子、孫のレコードを取得して ある書類を作成しエクセルに出力しようとしています。 この場合、親のデータは普通に変数Aに入れて 子のデータは一次元配列B()に入れ 孫のデータは一次元配列C(0)~C(3)に入れたものを、更に子用の一次元配列B1()~B4()に入れるように作りにしようと考えています。 この場合、 子の画面で次の2レコード目に進んだ時、子画面用のB1...B4の配列変数に入れている孫のC(0)~C(3)の配列の中身は、子画面の一レコードと二レコード目では同じものになるのでしょうか。 もし、同じものになるのであれば、この方法は使えないと思っていますが。。。 他に何か良い方法はありますでしょうか。 Accessで、クラスを作って、それを配列変数に入れるとか・・・ よろしくお願いします。