[Templates] Sticky forms with hierarchical template vars
Craig Barratt
craig@arraycomm.com
Mon, 07 Jan 2002 22:54:58 -0800
> I'd love to see an implementation that didn't need eval(), but I suspect
> it might be even harder to follow than this one.
Assuming I'm following what's needed, attached is a version that
doesn't use eval. It handles nested hashes and arrays, like your
version. It just loops right to left and builds up the data
structure, keeping track of what has already been built.
#!/bin/perl
use CGI;
use strict;
use Data::Dumper;
sub Flat2Nested
{
my($h) = @_;
my(%done);
foreach my $key ( keys(%$h) ) {
my($topKey, $lastKey, $new);
my $value = $h->{$key};
$topKey = $key;
while ( $topKey ne "" ) {
if ( $topKey =~ /(.*)\.(.*)/ ) {
$topKey = $1;
$lastKey = $2;
} else {
$lastKey = $topKey;
$topKey = "";
}
if ( defined($done{$topKey}) ) {
if ( ref $done{$topKey} eq "ARRAY" ) {
$done{$topKey}->[$lastKey] = $value;
} elsif ( ref $done{$topKey} eq "HASH" ) {
$done{$topKey}->{$lastKey} = $value;
}
last;
}
if ( $lastKey =~ /^\d+$/ ) {
$new = [];
$new->[$lastKey] = $value;
} else {
$new = {};
$new->{$lastKey} = $value;
}
$done{$topKey} = $new;
$value = $new;
}
}
return $done{""};
}
Here's an example call:
print Dumper(Flat2Nested({
'x' => 1,
'xx.yy.zz' => [2,3],
'xx.zz.0' => 4,
'xx.zz.1' => 5,
'xx.zz.2' => 6,
'xx.aa.0.a' => 7,
'xx.aa.0.b' => 8,
'xx.aa.0.c' => 9,
'xx.aa.1.d' => 10,
'xx.aa.1.e' => 11,
'xx.aa.1.f' => 12,
}));
which produces:
$VAR1 = {
'x' => 1,
'xx' => {
'aa' => [
{
'a' => 7,
'b' => 8,
'c' => 9
},
{
'e' => 11,
'f' => 12,
'd' => 10
}
],
'yy' => {
'zz' => [
2,
3
]
},
'zz' => [
4,
5,
6
]
}
};
Craig