如何让Data :: Diver生成数组?

时间:2014-12-23 21:38:40

标签: perl

以下脚本将输出

$VAR1 = {
          'tank' => {
                      'fs' => {
                                'fs2b' => undef,
                                'fs2a' => undef,
                                'fs2c' => undef
                              }
                    }
        };

我真的想要像这样的数组哈希哈希

$VAR1 = {
          'tank' => {
                      'fs' => [
                                'fs2a',
                                'fs2b',
                                'fs2c'
                              ]
                    }
        };

问题

如何使用Data::Diver完成?

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Data::Diver 'DiveRef';

my @array = ("tank", "tank/fs", "tank/fs/fs2a", "tank/fs/fs2b", "tank/fs/fs2c");
my %hash = ();

foreach my $element (@array) {
    DiveRef( \%hash, \( split /\//, $element ) );
}

print Dumper \%hash;

(由ysth this answer提供给另一个问题的代码。)

更新

代码中的数组只是一个例子。真实阵列有大约100个元素,因此解决方案不能被硬编码。

1 个答案:

答案 0 :(得分:1)

DiveVal(\%data, 'tank', 'fs', 0) = 'fs2a';
DiveVal(\%data, 'tank', 'fs', 1) = 'fs2b';
DiveVal(\%data, 'tank', 'fs', 2) = 'fs2c';

push @{ DiveVal(\%data, 'tank', 'fs') }, 'fs2a';
push @{ DiveVal(\%data, 'tank', 'fs') }, 'fs2b';
push @{ DiveVal(\%data, 'tank', 'fs') }, 'fs2c';

要从"tank", "tank/fs", "tank/fs/fs2a", "tank/fs/fs2b", "tank/fs/fs2c"获取所需的数据结构,需要额外的信息。举个例子,你可以理解数据结构总是一个HoHoA。

my @data = ("tank", "tank/fs", "tank/fs/fs2a", "tank/fs/fs2b", "tank/fs/fs2c");
my %data;
for (@data) {
   my @parts = split qr{/};
   if (@parts < 3) {
       DiveVal(\%data, map \$_, @parts);
   } else {
       my $val = pop(@parts);
       push @{ DiveVal(\%data, map \$_, @parts) }, $val; 
   }
}

但是这种有限的结构,没有理由使用Data :: Diver。避免它会快得多。

my @data = ("tank", "tank/fs", "tank/fs/fs2a", "tank/fs/fs2b", "tank/fs/fs2c");
my %data;
for (@data) {
   my @parts = split qr{/};
   if    (@parts == 1) { \( $data{$parts[0]}            ); }
   elsif (@parts == 2) { \( $data{$parts[0]}{$parts[1]} ); }
   else { push @{ $data{$parts[0]}{$parts[1]} }, $parts[2]; }
}

您甚至可以使用

my @data = ("tank", "tank/fs", "tank/fs/fs2a", "tank/fs/fs2b", "tank/fs/fs2c");
my %data;
for (@data) {
   my @parts = split qr{/};
   push @{ $data{$parts[0]}{$parts[1]} }, $parts[2] if @parts == 3;
}