在perl中,我如何引用父哈希中的哈希元素?

时间:2016-12-29 19:25:22

标签: perl hash

我已经编写了一个函数,通过将一个有序的键数组作为哈希的元素来按规定的顺序打印哈希值。

由于可能存在许多具有相同顺序的子查询,我希望能够将顺序字符串放在父哈希中,并在每个子哈希中引用它。 我无法让它工作,如下面的代码片段所示。

有办法做到这一点吗?

$hr={
    Order => [qw(Sp Ls)],
    OrderSP => [qw(a b)],
    Sp => {
        a =>-1, 
        b => -1,
        Order => @{$hr->{OrderSP}}
        },
    Ls => { 
        c => -1,
        d => -1,
        Order => [qw(c d)]
        }
    }; 
print "\n\@{\$hr->{OrderSP}} = ",@{$hr->{OrderSP}}; # ab
print "\n\@{\$hr->{Ls}->{Order}} = ",@{$hr->{Ls}->{Order}}; # cd 
print "\n\@{\$hr->{Sp}->{Order}} = ",@{$hr->{Sp}->{Order}}; # blank

Result:
@{$hr->{OrderSP}} = ab
@{$hr->{Ls}->{Order}} = cd
@{$hr->{Sp}->{Order}} =

1 个答案:

答案 0 :(得分:3)

是的,有办法做到这一点。

您的代码有两个问题:

  1. 您取消引用存储在父级中的arrayref:@{$hr->{OrderSP}}。这没有任何意义,因为散列中的值必须是单个标量,而不是列表。删除@{ }可以解决此问题。
  2. 最重要的一点:您正在尝试使用尚不存在的数据结构。虽然正在评估赋值的右侧(并且构造了哈希,子哈希等),但尚未触及$hr。实际分配仅在构建数据结构后发生。
  3. 这是一个有效的例子:

    use strict;
    use warnings;
    
    my $hr = {
        Order   => [qw(Sp Ls)],
        OrderSP => [qw(a b)],
        Sp => {
            a => -1, 
            b => -1,
        },
        Ls => { 
            c => -1,
            d => -1,
            Order => [qw(c d)],
        },
    };
    
    $hr->{Sp}{Order} = $hr->{OrderSP};
    
    print "\@{\$hr->{OrderSP}} = @{$hr->{OrderSP}}\n";
    print "\@{\$hr->{Ls}->{Order}} = @{$hr->{Ls}->{Order}}\n";
    print "\@{\$hr->{Sp}->{Order}} = @{$hr->{Sp}->{Order}}\n";
    

    输出:

    @{$hr->{OrderSP}} = a b
    @{$hr->{Ls}->{Order}} = c d
    @{$hr->{Sp}->{Order}} = a b
    

    关键是设置$hr->{Sp}{Order}已被拆分为单独的步骤,因此只有在$hr->{OrderSP}创建后才会发生(通过赋值给my $hr)。

    或者您也可以这样做:

    my $OrderSP = [qw(a b)];
    my $hr = {
        Order   => [qw(Sp Ls)],
        OrderSP => $OrderSP,
        Sp => {
            a => -1, 
            b => -1,
            Order => $OrderSP,
        },
        Ls => { 
            c => -1,
            d => -1,
            Order => [qw(c d)],
        },
    };
    

    这次我们不会在初始分配后修改$hr。相反,我们事先将OrderSP存储在一个单独的变量中,然后我们可以从任何地方引用它。

    (顺便说一下,我还修改了输出中的换行符。"\n"是一行终结符;即它位于每行的末尾,而不是开头。 )