Reputation: 9
I need to create multidimensional hashes with varying depth using array elements as keys. Pseudocode attempt:
Example line:
Statement Coverage for instance Hierarchical/path/with/block/and/module ...
if (/Statement Coverage for instance (.&?) /)
{
@array = split /\//, $1;
}
for (my $eye = 1; $eye <= $#array; $eye++)
{
A miracle happens to %hash!
}
$hash{"path"}{"with"}{"block"}{"and"} now has a value of "module". Remember, the number of keys can vary. Any ideas?
Upvotes: 0
Views: 230
Reputation: 3944
See my code below. It builds the desired hash recursively.
But I think that you are taking a wrong approach. I obviously don't know what exactly you are trying to achieve, but seems to me, that you should use tree data structure instead of the multidimensional hash.
use strict;
use warnings;
use v5.10;
use Data::Dumper;
my @data = (
'some/path/test',
'some/path/deeper/test',
'another/deeper/path/test',
);
my $resultHr = {};
foreach my $path (@data) {
my @elems = split /\//, $path;
buildHash($resultHr, @elems);
}
say Dumper($resultHr);
sub buildValue {
my $n = shift;
if (@_) {
return {$n => buildValue(@_)};
}
else {
return $n;
}
}
sub buildHash {
my $hr = shift;
my $k = shift;
return unless $k;
if (exists $hr->{$k} && ref $hr->{$k}) {
buildHash($hr->{$k}, @_);
}
else {
$hr->{$k} = buildValue(@_);
}
}
Upvotes: 1
Reputation: 242218
That's what Data::Diver does for you:
my @array = split /\//, $1;
DiveVal(\ my %hash, @array[ 0 .. $#array - 1 ]) = $array[-1];
print Dumper(\%hash);
Upvotes: 2