0

我想使用数组的结构对哈希进行哈希处理。每个数组元素都应该是前一个数组元素的子键。例如使用以下数组:

@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", 
          }, 
      }, 
  }, 
);

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

谢谢你的帮助。

4

1 回答 1

2

这对我来说听起来像是一个 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哪个大致完成了同样的事情。

于 2021-01-02T23:48:59.823 回答