0

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?

1
  • 1
    It's completely unclear what you're asking. Please learn about how to create a minimal reproducible example. Also, $eye? Commented May 5, 2016 at 16:43

2 Answers 2

2

That's what Data::Diver does for you:

my @array = split /\//, $1;
DiveVal(\ my %hash, @array[ 0 .. $#array - 1 ]) = $array[-1];
print Dumper(\%hash);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, unfortunately that package isn't installed on my system, at least for our rev of Perl, 5.8.8, and our IT department is very reluctant to upgrade. Maybe I can try it at home on my laptop.
5.8.8 is a very old version of perl
1

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(@_);
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.