在perl中动态创建哈希哈希

时间:2016-03-16 10:55:54

标签: perl hash hash-of-hashes

我正在尝试创建散列哈希 - 嵌套深度取决于传递到@aGroupByFields数组的参数数量。

在下面的实现中,我得到了所需的哈希结构。但是我对字段[example - $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
    );

}

任何指针都会很有帮助。谢谢。

2 个答案:

答案 0 :(得分:2)

以下是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"
                }
            ]
        }
    }
}

请注意,我重命名了您的变量。这样的代码很难阅读。对于变量的类型,只使用说话名称而不是隐秘缩写更有意义。这个印记已经为你做了。

答案 1 :(得分:1)

此代码将满足您的需求

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 } //= {};
        }
    }
}