使用字符串访问多维哈希

问题描述 投票:2回答:3

我有一个大的多维哈希,它是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.但是没有返回任何内容或者我发现错误“在连接中使用%bighash中的未初始化值(。)或在script.pl第1371行,第17行(#1)中使用字符串。 。

有人能指出我正在发生的事情吗?

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

谢谢!

perl hash
3个回答
1
投票

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

重新设想您的数据结构如下

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

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

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

这个代码的重写类似于ikegami wrote in his answer,但效率更低,更冗长。

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

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

print $value;

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


3
投票

有人能指出我正在进行的事情[当我使用$bighash{\%hash}时]?

散列键是字符串,\%hash的字符串化类似于HASH(0x655178)%bighash中唯一的元素有core-not HASH(0x655178)- for key,因此哈希查找返回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');

2
投票

Hash::Fold似乎在这里很有帮助。您可以“展平”您的哈希值,然后使用单个键访问所有内容。

use Hash::Fold 'flatten';
my $flathash = flatten(\%bighash, delimiter => '.');
print $flathash->{"core.dates.year"};
© www.soinside.com 2019 - 2024. All rights reserved.