的Perl:如何将数组嵌套的哈希键(Perl: How to turn array into nes

2019-06-26 07:53发布

我需要钥匙的平面列表转换成一个嵌套的哈希值,如下:

我的$哈希= {};

我的@array = QW(KEY1 KEY2值的lastKey);

ToNestedHash($哈希,@array);

这样做:

$哈希{ 'KEY1'} { 'KEY2'} { '的lastKey'} = “值”;

Answer 1:

sub to_nested_hash {
    my $ref   = \shift;  
    my $h     = $$ref;
    my $value = pop;
    $ref      = \$$ref->{ $_ } foreach @_;
    $$ref     = $value;
    return $h;
}

说明:

  • 先取值作为hashref
  • 就拿最后一个值,作为分配价值
  • 其余的都是钥匙。
  • 然后,创建一个SCALAR参考基础散列。
  • 反复:
    • 解除引用指针,以获得散列(第一次)或autovivify指针作为散列
    • 获取密钥的哈希位置
    • 并分配标参考哈希位置。
    • (解决此下次还会autovivify到指定的哈希值)。
  • 最后,与参考到最里面的槽,分配的值。

我们知道:

  • 该散列或阵列的居住者只能是一个标量或参考。
  • 这一提的是各种各样的标量。 ( my $h = {}; my $a = [];
  • 因此,\ $ H - > {$ key}的是一个标量插槽的引用在堆上,也许autovivified。
  • 一个嵌套哈希的“级别”,可以autovivified到哈希引用,如果我们解决它如此。

这可能是更明确的做到这一点:

foreach my $key ( @_ ) { 
    my $lvl = $$ref = {};
    $ref    = \$lvl->{ $key };
}

但是,由于重复使用这些引用的成语,我写这句话完全,因为它是和发布前测试它,而不会出现错误。

作为替代方案,下面的版本是“容易”(想出)

sub to_nested_hash {
    $_[0] //= {};
    my $h     = shift;
    my $value = pop;
    eval '$h'.(join '', map "->{\$_[$i]}", 0..$#_).' = $value';
    return $h;
}

但是约6-7倍慢。



Answer 2:

Thxs的好东西!

我这样做,是递归的方式:

sub Hash2Array
{
  my $this = shift;
  my $hash = shift;

  my @array;
  foreach my $k(sort keys %$hash)
  {
    my $v = $hash->{$k};
    push @array,
      ref $v eq "HASH" ? $this->Hash2Array($v, @_, $k) : [ @_, $k, $v ];
  }

  return @array;
}

这将是有趣的,有所有这些解决方案之间的性能比较...



Answer 3:

我认为这个代码是更好 - 更适合于移动到一个类的方法,和任选地设置一个值,这取决于所提供的参数。 否则,所选择的答案是整齐的。

#!/usr/bin/env perl

use strict;
use warnings;
use YAML;

my $hash = {};

my @array = qw(key1 key2 lastKey);
my $val = [qw/some arbitrary data/];

print Dump to_nested_hash($hash, \@array, $val);
print Dump to_nested_hash($hash, \@array);
sub to_nested_hash {
    my ($hash, $array, $val) = @_;
    my $ref   = \$hash;
    my @path = @$array;
    print "ref: $ref\n";
    my $h     = $$ref;
    $ref      = \$$ref->{ $_ } foreach @path;
    $$ref     = $val if $val;
    return $h;
}


文章来源: Perl: How to turn array into nested hash keys