我有一个哈希数组,其中许多都有共享密钥。
我想将其转换为在[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
答案 0 :(得分: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 :(得分: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 :(得分: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";
}