Perl:如何将数组转换为嵌套的哈希键
问题描述:
我需要将一个简单的键列表转换成一个嵌套的散列,如下所示:
I need to convert a flat list of keys into a nested hash, as follow:
我的 $hash = {};
my $hash = {};
我的@array = qw(key1 key2 lastKey Value);
my @array = qw(key1 key2 lastKey Value);
ToNestedHash($hash, @array);
ToNestedHash($hash, @array);
会这样做:
$hash{'key1'}{'key2'}{'lastKey'} = "Value";
$hash{'key1'}{'key2'}{'lastKey'} = "Value";
答
sub to_nested_hash {
my $ref = \shift;
my $h = $$ref;
my $value = pop;
$ref = \$$ref->{ $_ } foreach @_;
$$ref = $value;
return $h;
}
说明:
- 将第一个值作为哈希引用
- 取最后一个值作为赋值
- 剩下的就是钥匙了.
- 然后创建一个对基本哈希的 SCALAR 引用.
- 反复:
- 取消引用指针以获取散列(第一次)或将指针自动激活为散列
- 获取密钥的哈希槽
- 并将标量引用分配给哈希槽.
- (下次将自动激活到指定的哈希值).
我们知道:
- 散列或数组的占用者只能是标量或引用.
- 引用是某种标量.(
my $h = {}; my $a = [];
). - 所以,\$h->{ $key } 是对堆上标量槽的引用,可能是自动激活的.
- 嵌套散列的级别"可以自动激活为散列引用如果我们如此处理它.
- That the occupants of a hash or array can only be a scalar or reference.
- That a reference is a scalar of sorts. (
my $h = {}; my $a = [];
). - So, \$h->{ $key } is a reference to a scalar slot on the heap, perhaps autovivified.
- That a "level" of a nested hash can be autovivified to a hash reference if we address it as so.
这样做可能更明确:
foreach my $key ( @_ ) { my $lvl = $$ref = {}; $ref = \$lvl->{ $key }; }
但由于重复使用这些参考习语,我完全照原样写了那行,并在发布前对其进行了测试,没有错误.
But owing to repeated use of these reference idioms, I wrote that line totally as it was and tested it before posting, without error.
至于替代方案,以下版本更容易"(想出来)
As for alternatives, the following version is "easier" (to think up)
sub to_nested_hash { $_[0] //= {}; my $h = shift; my $value = pop; eval '$h'.(join '', map "->{\$_[$i]}", 0..$#_).' = $value'; return $h; }
但大约慢 6-7 倍.
But about 6-7 times slower.