Perl:如何在键来自数组的情况下生成散列的散列
Perl: How to make hash of hash where keys come from an array
我想用数组的结构做一个散列的散列。每个数组元素应该是前一个数组元素的子键。例如使用以下数组:
@array1 = ("animal","dog","sparky");
@array2 = ("animal","cat","felix");
@array3 = ("animal","bird","penguin","skipper");
我想制作一个结构如下的散列:
$hash{"动物"}{"狗"}{"火花"} = 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
,它大致完成了同样的事情。
我想用数组的结构做一个散列的散列。每个数组元素应该是前一个数组元素的子键。例如使用以下数组:
@array1 = ("animal","dog","sparky");
@array2 = ("animal","cat","felix");
@array3 = ("animal","bird","penguin","skipper");
我想制作一个结构如下的散列:
$hash{"动物"}{"狗"}{"火花"} = 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
,它大致完成了同样的事情。