2012-01-23 30 views
3

私はハッシュの配列を持っており、その多くは共有キーを持っています。Perl:ハッシュの配列を行列に変換する

これは、各行がハッシュを表し、各ユニークキーが(空白)または '。'の列であるように、[R]で解析するための行列に変換したいと思います。ハッシュにその特定のキーが含まれていない場合は 'NA'。

現在、私は、ハッシュの配列内のそれぞれのユニークなキーを見つけ出し、それぞれのハッシュについてそれぞれをループすることで自分のマトリックスを構築するつもりですが、より良い方法が必要ですか?

ありがとうございます!

例:

my %hash_A = (
    A=> 12, 
    B=> 23, 
    C=> 'a string' 
); 
my %hash_B = (
    B=> 23, 
    C=> 'a different string', 
    D=> 99 
); 

与えること:

A,B,C,D 
12,23,'a string',NA 
NA, 23, 'a different string', 99 
+1

あなたはあなたのデータ構造と所望の出力の小さな例を示してもらえますか? – dgw

+0

私は[PDL](http://pdl.perl.org)のユーザーではありませんが、これはグループが頻繁に行う必要があり、簡単なやり方があると思われるようなものです。 – Joe

答えて

1

これは、ハッシュの配列を2D配列(@output1)に変換する必要があります。

対応する入力値がなかったすべての出力セルには、'NA'が入力されます。 (あなたがマップされていない細胞がundefにマッピングされて気にしない場合、これはより簡潔に行うことができます - @output2を参照してください。)

配列@keysは、出力行の各インデックス位置を関係するハッシュキーと言うだろう。

my @array_of_hashes = ...; 

my %keys 

for my $hash (@array_of_hashes) { 
    @keys{keys %$hash} =(); 
} 

my @keys = sort keys %keys; 

my @output1 = map { 
    my $hash = $_; 

    [ map { exists $$hash{$_} ? $$hash{$_} : 'NA' } @keys ]; 
} @array_of_hashes; 

my @output2 = map [ @$_{@keys} ] => @array_of_hashes; 
2

をあなたのハッシュのそれぞれが、各可能なキーのために、「NA」に初期化されていることを確認した場合、あなたは基本的に行列を持っていて、それを印刷するだけです(データが "NA"でない場合は上書きされます)

初期化できない場合は、事前にすべてのキーを追跡してループしてください(個々のハッシュのキーをループするのではなく)データ構造を印刷します。

 
my @possibleKeys = keys %possibleKeys; 
foreach my $hashref (@arrayOfHashes) 
    foreach my $key (@possibleKeys) { 
     if(!defined ${$hashref}{$key}) { 
      print "NA "; 
     else { 
      print "$hashref{$key} "; 
     } 
    print "\n"; 
    } 
} 

編集: keys %possibleKeysは呼び出しごとに異なった規則的な配列を返します(http://perldoc.perl.org/functions/keys.htmlを参照)そのためのキーは、順序を維持するために、配列に格納する必要があります。

1
my @a = (keys %hash_A, keys %hash_B); 
my %r; 
@r{@a} = @a; 
for my $h (\%r, \%hash_A, \%hash_B) { 
    print join(', ', map { $$h{$_} ||= 'NA' } sort keys %r), "\n"; 
} 
関連する問題