使用字符串访问多维哈希

时间:2019-02-26 14:59:10

标签: perl hash

我有一个很大的多维哈希,它是JSON结构的导入。

my %bighash;

%bighash中有一个元素叫做:

$bighash{'core'}{'dates'}{'year'} = 2019.

我有一个单独的字符串变量,称为core.dates.year,我想用它从%bighash中提取2019。

我已经编写了这段代码:

my @keys  = split(/\./, 'core.dates.year');
my %hash = ();
my $hash_ref = \%hash;

for my $key ( @keys ){
    $hash_ref->{$key} = {};
    $hash_ref = $hash_ref->{$key};
}

执行该命令时

say Dumper \%hash;

输出:

$VAR1 = {
          'core' => {
                   'dates' => {
                             'year' => {}
                           }
                 }
        };

到目前为止一切都很好。但是我现在要说的是:

print $bighash{\%hash};

我想返回2019。但是什么都没有返回,或者我看到有关“在script.pl第1371行,第17行(#1)的串联(。)或字符串中使用%bighash中未初始化的值的错误。 )...

有人可以指出我的情况吗?

我的项目涉及将字符串嵌入到外部文件中,然后将其替换为%bighash中的实际值,因此它只是字符串插值。

谢谢!

3 个答案:

答案 0 :(得分:3)

  

有人可以指出[正在使用$bighash{\%hash}的情况吗?

哈希键是字符串,\%hash的字符串化类似于HASH(0x655178)%bighash中唯一的元素具有core(而非HASH(0x655178))作为密钥,因此哈希查找返回undef


有用的工具:

sub dive_val :lvalue { my $p = \shift; $p //= \( $$p->{$_} ) for @_; $$p }   # For setting
sub dive { my $r = shift; $r //= $r->{$_} for @_; $r }                       # For getting

dive_val(\%hash, split /\./, 'core.dates.year') = 2019;
say dive(\%hash, split /\./, 'core.dates.year');

答案 1 :(得分:2)

Hash::Fold在这里似乎会有所帮助。您可以“整理”您的哈希,然后使用一个键访问所有内容。

use Hash::Fold 'flatten';
my $flathash = flatten(\%bighash, delimiter => '.');
print $flathash->{"core.dates.year"};

答案 2 :(得分:1)

Perl中没有多维哈希。哈希是键/值对。您对Perl数据结构的了解不完整。

重新构想您的数据结构,如下所示

my %bighash = (
    core => {
        dates => {
            year => 2019,
        },
    },
);

圆括号()和花括号{}之间有区别。变量名称上的%符号表示它是一个散列,即一组无序的键/值对。回合()是一个列表。该列表内有两个标量值,即一个键和一个值。该值是对另一个匿名哈希的引用。这就是为什么它{}卷曲的原因。

每个级别都是一个单独的,不同的数据结构。

您的代码重写与ikegami wrote in his answer类似,但效率较低且冗长。

my @keys = split( /\./, 'core.dates.year' );

my $value = \%bighash;
for my $key (@keys) {
  $value //= $value->{$key};
}

print $value;

它将逐步深入到结构中,并最终为您提供最终的价值。