【问题标题】:Creating hash of hash dynamically in perl在 perl 中动态创建散列的散列
【发布时间】:2016-07-02 05:03:03
【问题描述】:

我正在尝试创建一个散列的散列 - 嵌套深度取决于传递给 @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
    );

}

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

【问题讨论】:

  • 您不想生成语句。您想生成哈希。但是你为什么想要那个?
  • 请参考以下问题:stackoverflow.com/questions/4558981/…希望对您有所帮助!
  • @simbabque : 这样生成的哈希将用于呈现错误报告。然后错误报告将能够显示按 createdBy > status > devPriority 分组的错误。 [简而言之,我得到了一个 groupBy 字段列表和所有错误记录的转储 - 我需要返回一个哈希值,该哈希值应该对错误记录进行适当的分组]。无论如何感谢您的编辑。干杯。
  • @HåkonHægland 我不知道 Data::Diver。这很有趣,尤其是它可以是左值。 :)

标签: perl hash hash-of-hashes


【解决方案1】:

这是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,只使用口语名称而不是隐晦的缩写会更有意义。印记已经为你做到了。

【讨论】:

    【解决方案2】:

    此代码将满足您的需求

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

    【讨论】:

    • 这就像一个魅力。把我想要的东西还给我。我知道我在这里要求太多 - 你能解释一下代码 $hash = $hash->{ $key } / /= {};非常感谢您的意见。
    猜你喜欢
    • 2013-07-19
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 2015-11-16
    • 2013-09-10
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多