Perl:如何在密钥来自数组的地方进行散列



我想使用数组的结构生成一个hash的hash。每个数组元素都应该是前一个数组元素的一个子键。例如,使用以下阵列:

@array1 = ("animal","dog","sparky");
@array2 = ("animal","cat","felix");
@array3 = ("animal","bird","penguin","skipper");

我想制作一个结构如下的散列:

$hash{"animal"}{"dog"}{"sparky"}=1;

%hash = ( 
"animal" => { 
"dog" => {
"sparky" => "1", 
}, 
"cat" => {
"felix" => "1", 
}, 
"bird" => {
"penguin" => {
"skippy" => "1", 
}, 
}, 
}, 
);

数组的元素数量并不总是相同。但它应该建造同样的结构。

谢谢你的帮助。

对我来说,这听起来像是一个XY问题——我非常怀疑你有3个单独的编号数组。

但我会在你看到更普遍的情况时回答——做这类事情的诀窍是使用哈希引用来遍历和重置。

use Data::Dumper;
my %hash; 
my @array1 = ("animal","bird","penguin","skipper");
my $cursor = %hash; 

foreach my $element (  @array1 ) {  
$cursor -> {$element} //= {};
$cursor = $cursor -> {$element};
}
$cursor = 1; 
print Dumper %hash;

因此,我们沿着您的数据结构往下走;并创建一个子元素-使用//=创建一个新的子灰,如果-并且仅当-还没有定义子灰。

所以对于你的整套:

use strict;
use warnings;
use Data::Dumper;
my %hash;
my @array1 = ( "animal", "dog",  "sparky" );
my @array2 = ( "animal", "cat",  "felix" );
my @array3 = ( "animal", "bird", "penguin", "skipper" );
my $cursor = %hash;
foreach my $array ( @array1, @array2, @array3 ) {
foreach my $element (@$array) {
$cursor->{$element} //= {};
$cursor = $cursor->{$element};
}
$cursor = 1;
$cursor = %hash;
}
print Dumper %hash;

现在请注意,这并没有达到预期的结果,因为我们创建了空哈希来填充您的结构。所以最底层是{}——一个空散列——而不是您要查找的1

$VAR1 = {
'animal' => {
'dog' => {
'sparky' => {}
},
'bird' => {
'penguin' => {
'skipper' => {}
}
},
'cat' => {
'felix' => {}
}
}
};

但希望这能让你知道如何解决这个问题?

值得一看的是,什么是自动激活,它在做什么-通常它是有帮助的,但对于构建这种数据结构来说,它可能不是。我们已经在每个键下面明确创建了一个空的子灰,但前提是它还不存在。

因此,为了完成你想要做的事情——我们实际上需要以不同的方式处理最后一个元素——我们不是试图创建和清空子灰,而是试图设置一个值。

因此:

use strict;
use warnings;
use Data::Dumper;
my %hash;
my @array1 = ( "animal", "dog",  "sparky" );
my @array2 = ( "animal", "cat",  "felix" );
my @array3 = ( "animal", "bird", "penguin", "skipper" );
my $cursor = %hash;
foreach my $array ( @array1, @array2, @array3 ) {
# remove the last value from the array
my $last =  pop @$array;
foreach my $element (@$array) {
$cursor->{$element} //= {};
$cursor = $cursor->{$element};
}
#set the last value to be '1' instead of a subhash.
#Otherwise it'll be created by the //= line above, and be an empty hash. 
$cursor -> {$last} = 1;
$cursor  = %hash;
}
print Dumper %hash;

这给了我们想要的结果:

$VAR1 = {
'animal' => {
'dog' => {
'sparky' => 1
},
'bird' => {
'penguin' => {
'skipper' => 1
}
},
'cat' => {
'felix' => 1
}
}

或者你可以看看Data::Diver,它大致完成了同样的事情。

最新更新