在perl中动态创建散列的散列
Creating hash of hash dynamically in perl
我正在尝试创建一个散列的散列 - 嵌套深度取决于传入 @aGroupByFields
数组的参数数量。
在下面的实现中,我得到了所需的散列 structure.But 我已经对字段进行了硬编码 [示例 - $phBugRecord->{createdBy}
] 而不是从数组中派生它。
我不知道如何动态创建它。
my (@aGroupByFields) = ['createdBy','status','devPriority'];
# In real case,these are passed in as arguments
my (%hTemp);
# This is the final hash which will be structured according to above fields
# %hBugDetails is the hash containing details of all bugs
foreach my $phBugRecord ( @{ $hBugDetails{records} } ) {
# The below statement needs to be generated dynamically as
# opposed to the hard-coded values.
push(
@{
$hTemp{ $phBugRecord->{createdBy} }{ $phBugRecord->{status} }
{ $phBugRecord->{devPriority} }
},
$phBugRecord
);
}
任何指针都是很好的help.Thanks。
这是 Data::Diver 的有效实现。
use strict;
use warnings;
use Data::Diver 'DiveVal';
use Data::Printer;
my %hBugDetails = (
records => [
{
createdBy => 'created_by1',
status => 'status1',
devPriority => 'dev_priority1',
foo => 'foo1',
bar => 'bar1',
},
{
createdBy => 'created_by1',
status => 'status2',
devPriority => 'dev_priority2',
foo => 'foo',
bar => 'bar',
},
],
);
# we want to group by these fields
my @group_by = ( 'createdBy', 'status', 'devPriority' );
my $grouped_bugs = {}; # for some reason we need to start with an empty hashref
foreach my $bug ( @{ $hBugDetails{records} } ) {
# this will auto-vivify the hash for us
push @{ DiveVal( $grouped_bugs, map { $bug->{$_} } @group_by ) }, $bug;
}
p $grouped_bugs;
输出如下所示。
\ {
created_by1 {
status1 {
dev_priority1 [
[0] {
bar "bar1",
createdBy "created_by1",
devPriority "dev_priority1",
foo "foo1",
status "status1"
}
]
},
status2 {
dev_priority2 [
[0] {
bar "bar",
createdBy "created_by1",
devPriority "dev_priority2",
foo "foo",
status "status2"
}
]
}
}
}
请注意,我重命名了您的变量。像这样阅读代码非常困难。对于变量的 type,只使用说话的名字而不是神秘的缩写更有意义。印记已经为你做到了。
此代码将满足您的需求
my @aGroupByFields = qw/ createdBy status devPriority /;
my %hTemp;
for my $phBugRecord ( @{ $hBugDetails{records} } ) {
my $hash = \%hTemp;
for my $field ( @aGroupByFields ) {
my $key = $phBugRecord->{$field};
if ( $field eq $aGroupByFields[-1] ) {
push @{ $hash->{ $key } }, $phBugRecord;
}
else {
$hash = $hash->{ $key } //= {};
}
}
}
我正在尝试创建一个散列的散列 - 嵌套深度取决于传入 @aGroupByFields
数组的参数数量。
在下面的实现中,我得到了所需的散列 structure.But 我已经对字段进行了硬编码 [示例 - $phBugRecord->{createdBy}
] 而不是从数组中派生它。
我不知道如何动态创建它。
my (@aGroupByFields) = ['createdBy','status','devPriority'];
# In real case,these are passed in as arguments
my (%hTemp);
# This is the final hash which will be structured according to above fields
# %hBugDetails is the hash containing details of all bugs
foreach my $phBugRecord ( @{ $hBugDetails{records} } ) {
# The below statement needs to be generated dynamically as
# opposed to the hard-coded values.
push(
@{
$hTemp{ $phBugRecord->{createdBy} }{ $phBugRecord->{status} }
{ $phBugRecord->{devPriority} }
},
$phBugRecord
);
}
任何指针都是很好的help.Thanks。
这是 Data::Diver 的有效实现。
use strict;
use warnings;
use Data::Diver 'DiveVal';
use Data::Printer;
my %hBugDetails = (
records => [
{
createdBy => 'created_by1',
status => 'status1',
devPriority => 'dev_priority1',
foo => 'foo1',
bar => 'bar1',
},
{
createdBy => 'created_by1',
status => 'status2',
devPriority => 'dev_priority2',
foo => 'foo',
bar => 'bar',
},
],
);
# we want to group by these fields
my @group_by = ( 'createdBy', 'status', 'devPriority' );
my $grouped_bugs = {}; # for some reason we need to start with an empty hashref
foreach my $bug ( @{ $hBugDetails{records} } ) {
# this will auto-vivify the hash for us
push @{ DiveVal( $grouped_bugs, map { $bug->{$_} } @group_by ) }, $bug;
}
p $grouped_bugs;
输出如下所示。
\ {
created_by1 {
status1 {
dev_priority1 [
[0] {
bar "bar1",
createdBy "created_by1",
devPriority "dev_priority1",
foo "foo1",
status "status1"
}
]
},
status2 {
dev_priority2 [
[0] {
bar "bar",
createdBy "created_by1",
devPriority "dev_priority2",
foo "foo",
status "status2"
}
]
}
}
}
请注意,我重命名了您的变量。像这样阅读代码非常困难。对于变量的 type,只使用说话的名字而不是神秘的缩写更有意义。印记已经为你做到了。
此代码将满足您的需求
my @aGroupByFields = qw/ createdBy status devPriority /;
my %hTemp;
for my $phBugRecord ( @{ $hBugDetails{records} } ) {
my $hash = \%hTemp;
for my $field ( @aGroupByFields ) {
my $key = $phBugRecord->{$field};
if ( $field eq $aGroupByFields[-1] ) {
push @{ $hash->{ $key } }, $phBugRecord;
}
else {
$hash = $hash->{ $key } //= {};
}
}
}