Dav*_*d B 4 perl hash perl-data-structures
我有一组哈希,都有相同的键组,例如:
my $aoa= [
{NAME=>'Dave', AGE=>12, SEX=>'M', ID=>123456, NATIONALITY=>'Swedish'},
{NAME=>'Susan', AGE=>36, SEX=>'F', ID=>543210, NATIONALITY=>'Swedish'},
{NAME=>'Bart', AGE=>120, SEX=>'M', ID=>987654, NATIONALITY=>'British'},
]
Run Code Online (Sandbox Code Playgroud)
我想编写一个子程序,它将使用给定的键层次结构将其转换为哈希哈希值:
my $key_hierarchy_a = ['SEX', 'NATIONALITY'];
aoh_to_hoh ($aoa, $key_hierarchy_a) = @_;
...
}
Run Code Online (Sandbox Code Playgroud)
将返回
{M=>
{Swedish=>{{NAME=>'Dave', AGE=>12, ID=>123456}},
British=>{{NAME=>'Bart', AGE=>120, ID=>987654}}},
F=>
{Swedish=>{{NAME=>'Susan', AGE=>36, ID=>543210}}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不仅会创建正确的密钥层次结构,还会删除现在的冗余密钥.
我陷入困境,需要在正确的分层位置创建新的,最内部的哈希.
问题是我不知道"深度"(即键的数量).如果我有一个常数,我可以这样做:
%h{$inner_hash{$PRIMARY_KEY}}{$inner_hash{$SECONDARY_KEY}}{...} = filter_copy($inner_hash,[$PRIMARY_KEY,$SECONDARY_KEY])
Run Code Online (Sandbox Code Playgroud)
所以也许我可以编写一个循环,一次添加一个级别,从散列中删除该键,而不是将剩余的散列添加到"当前"位置,但它有点麻烦,我也不知道如何保持哈希散列中的"位置"......
use Data::Dumper;
my $aoa= [
{NAME=>'Dave', AGE=>12, SEX=>'M', ID=>123456, NATIONALITY=>'Swedish'},
{NAME=>'Susan', AGE=>36, SEX=>'F', ID=>543210, NATIONALITY=>'Swedish'},
{NAME=>'Bart', AGE=>120, SEX=>'M', ID=>987654, NATIONALITY=>'British'},
];
sub aoh_to_hoh {
my ($aoa, $key_hierarchy_a) = @_;
my $result = {};
my $last_key = $key_hierarchy_a->[-1];
foreach my $orig_element (@$aoa) {
my $cur = $result;
# song and dance to clone an element
my %element = %$orig_element;
foreach my $key (@$key_hierarchy_a) {
my $value = delete $element{$key};
if ($key eq $last_key) {
$cur->{$value} ||= [];
push @{$cur->{$value}}, \%element;
} else {
$cur->{$value} ||= {};
$cur = $cur->{$value};
}
}
}
return $result;
}
my $key_hierarchy_a = ['SEX', 'NATIONALITY'];
print Dumper(aoh_to_hoh($aoa, $key_hierarchy_a));
Run Code Online (Sandbox Code Playgroud)
根据@ FM的评论,你真的想要一个额外的数组级别.
输出:
$VAR1 = {
'F' => {
'Swedish' => [
{
'ID' => 543210,
'NAME' => 'Susan',
'AGE' => 36
}
]
},
'M' => {
'British' => [
{
'ID' => 987654,
'NAME' => 'Bart',
'AGE' => 120
}
],
'Swedish' => [
{
'ID' => 123456,
'NAME' => 'Dave',
'AGE' => 12
}
]
}
};
Run Code Online (Sandbox Code Playgroud)
编辑:哦,顺便说一句 - 如果有人知道如何优雅地克隆参考的内容,请教.谢谢!
编辑编辑:@FM帮助.现在好多了:D