Need a little help creating hashrefs of hashrefs, with the last key as a reference to an array.
use Data::Dumper;
my $foo = "a:b:c:d:a";
my $bar = "a:b:c:d:z";
my $hoh = {};
sub createHash {
my ($hoh,$orig,$rest,$last) = @_;
$rest = $rest || $orig;
$_ = $rest;
if (/^(.*?):(.*)$/) {
$hoh->{$1} = $hoh->{$1} || {};
createHash($hoh->{$1},$orig,$2,$1);
}
elsif (defined($last)) {
push (@{$hoh->{value}} , [$rest,$orig]);
}
return $hoh;
}
$hoh = createHash($hoh,$foo,undef);
$hoh = createHash($hoh,$bar,undef);
print Dumper($hoh);
What's Wanted:
$VAR1 = {
'a' => {
'b' => {
'c' => {
'd' => [
[
'a',
'a:b:c:d:a'
],
[
'z',
'a:b:c:d:z'
]
]
}
}
}
};
You can compare this with the output from codepad. Notice the subtle difference; instead of 'd' being a hashref that has an arrayref value
, 'd' is the arrayref and there is no value
.
I'd suggest Data::Diver, though it is a bit awkward since it wants to always create scalar references at the end, and that's not what we want. Thus, I cheat a bit.
The main thing here is that we can save effort (mostly in maintenance) by deciphering all the keys at once, and using a while loop (inside Data::Diver) instead of recursion, which is, by its nature, a bit more fun to decipher :-) Combine that with the fact that even if it were recursion, it'd be hidden in a nice, neat function call, it's a double win :-)
Hope that helps,
UPDATE: After conversing with tye, he provided a more concise way to do this. It uses Data::Diver still, but has a much simpler workaround embedded. (His claim is that perl has a bug here with :lvalue subs and push - I don't know better, so I'll take his word.)