我有一个大的多维哈希,它是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中没有多维哈希。哈希是键/值对。您对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;
它逐步深入到结构中并最终为您提供最终值。
有人能指出我正在进行的事情[当我使用
$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');
Hash::Fold
似乎在这里很有帮助。您可以“展平”您的哈希值,然后使用单个键访问所有内容。
use Hash::Fold 'flatten';
my $flathash = flatten(\%bighash, delimiter => '.');
print $flathash->{"core.dates.year"};