perl - 如何从 Perl 中的散列数组创建散列散列?

标签 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'},
]

我想编写一个子例程,使用给定的键层次结构将其转换为散列的散列:
my $key_hierarchy_a = ['SEX', 'NATIONALITY'];
aoh_to_hoh ($aoa, $key_hierarchy_a) = @_;
 ...
}

将返回
{M=>
  {Swedish=>{{NAME=>'Dave', AGE=>12, ID=>123456}},
   British=>{{NAME=>'Bart', AGE=>120, ID=>987654}}}, 
 F=>
  {Swedish=>{{NAME=>'Susan', AGE=>36,  ID=>543210}}
}

请注意,这不仅会创建正确的 key 层次结构,还会删除现在冗余的 key 。

我陷入了需要在其正确的层次结构位置创建新的最内部散列的点。

问题是我不知道“深度”(即键数)。如果我有一个常数,我可以这样做:
%h{$inner_hash{$PRIMARY_KEY}}{$inner_hash{$SECONDARY_KEY}}{...} = filter_copy($inner_hash,[$PRIMARY_KEY,$SECONDARY_KEY])

所以也许我可以编写一个循环,一次添加一个级别,从哈希中删除该键,而不是将剩余的哈希添加到“当前”位置,但这有点麻烦,而且我不知道如何保持哈希散列中的“位置”...

最佳答案

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));

根据@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
                                  }
                                ]
                 }
        };

编辑:哦,顺便说一句 - 如果有人知道如何优雅地克隆引用文献的内容,请教。谢谢!

编辑 编辑:@FM 有帮助。现在一切都好:D

关于perl - 如何从 Perl 中的散列数组创建散列散列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3849825/

相关文章:

c++ - 二进制读取mp3文件的ID3标签

linux - 写入许多文件的替代方案。 MongoDB?

javascript - window.location.hash = '' 不删除哈希本身

perl - 如何在 Perl 中将多个哈希合并为一个哈希?

perl - 为 OS X 构建 Perl - 架构特定的编译选项

linux - 如何在同一文件中添加行数

node.js - 将密码哈希脚本从 GO 转换为 Nodejs

perl - 如何在 perl 中按降序对散列值进行排序?

arrays - 散列数组中的散列

algorithm - 给定节点关系数据结构,如何对父子列表进行排序?