J
JR
Hi. Is it possible to create a subroutine to handle an arbitrarily
complex data structure (for my purposes, complex only refers to hashes
and arrays)? In the below examples, I have a hash of hashes, and an
array of arrays, and then a fairly weak subroutine to handle the
individual processing of each. However, I don't know how to handle an
arbitrarily complex data structure, such as a hash of array of hash of
arrays. Is there any means by which to handle such a data structure
in a common subroutine, such as the below one, that can individually
handle a given hash of hashes or array of arrays? I ask because I may
need to be able to process a given data structure, but will not know
the complexity of said structure, other than that it will only include
combinations of arrays and hashes (the data structures will be placed
in various flat ascii files and sent to me).
#!/perl
use strict;
use warnings;
use diagnostics;
my %hoh = (
h1 => {
h1 => "v1",
h2 => "v2",
},
h2 => {
h3 => "v3",
h4 => "v4",
},
h3 => {
h5 => "v5",
h6 => "v6",
},
);
my @aoa = (
[ 0, 1, 2 ],
[ 3, 4, 5 ],
[ 6, 7, 8 ],
);
my %hoa = (
flinstones => [ "fred", "barney" ],
jetsones => [ "george", "jane", "elroy" ],
simpsons => [ "homer", "marge", "bart" ],
);
sub T {
## The '|| "@_" =~ /HASH/' statement is needed because
## perl does not recognize the apparent address of
## HASH(0x1ab2eb4) with the ref function---this
## code can easily break.
if (ref(@_) eq 'HASH' || "@_" =~ /HASH/) {
my $x = shift;
while (my($k, $v) = each %$x) {
if (ref($v) eq 'HASH') {
print "\n$k\n";
T($v);
}
else {
print "$k=$v\n";
}
}
}
else {
for (0..$#_) {
my $e = $_[$_];
if (ref($e) eq 'ARRAY') {
T(@$e);
}
else {
print "$e\n";
}
}
}
}
T(\@aoa); # succeeds
T(\%hoh); # succeeds
T(\%hoa); # fails
=pod
# OUTPUT of failure
simpsons=ARRAY(0x1ab2da0)
jetsones=ARRAY(0x1ab56f4)
flinstones=ARRAY(0x1ab558c)
=cut
## One standard means of printing %hoa--how can I possibly
## code something such as this for an arbitrarily complex
## data structure?
print "$_ @{ $hoa{$_} }\n" for (sort keys %hoa);
Thanks in advance to anyone who offers any advice on how to solve the
above problem.
JR
complex data structure (for my purposes, complex only refers to hashes
and arrays)? In the below examples, I have a hash of hashes, and an
array of arrays, and then a fairly weak subroutine to handle the
individual processing of each. However, I don't know how to handle an
arbitrarily complex data structure, such as a hash of array of hash of
arrays. Is there any means by which to handle such a data structure
in a common subroutine, such as the below one, that can individually
handle a given hash of hashes or array of arrays? I ask because I may
need to be able to process a given data structure, but will not know
the complexity of said structure, other than that it will only include
combinations of arrays and hashes (the data structures will be placed
in various flat ascii files and sent to me).
#!/perl
use strict;
use warnings;
use diagnostics;
my %hoh = (
h1 => {
h1 => "v1",
h2 => "v2",
},
h2 => {
h3 => "v3",
h4 => "v4",
},
h3 => {
h5 => "v5",
h6 => "v6",
},
);
my @aoa = (
[ 0, 1, 2 ],
[ 3, 4, 5 ],
[ 6, 7, 8 ],
);
my %hoa = (
flinstones => [ "fred", "barney" ],
jetsones => [ "george", "jane", "elroy" ],
simpsons => [ "homer", "marge", "bart" ],
);
sub T {
## The '|| "@_" =~ /HASH/' statement is needed because
## perl does not recognize the apparent address of
## HASH(0x1ab2eb4) with the ref function---this
## code can easily break.
if (ref(@_) eq 'HASH' || "@_" =~ /HASH/) {
my $x = shift;
while (my($k, $v) = each %$x) {
if (ref($v) eq 'HASH') {
print "\n$k\n";
T($v);
}
else {
print "$k=$v\n";
}
}
}
else {
for (0..$#_) {
my $e = $_[$_];
if (ref($e) eq 'ARRAY') {
T(@$e);
}
else {
print "$e\n";
}
}
}
}
T(\@aoa); # succeeds
T(\%hoh); # succeeds
T(\%hoa); # fails
=pod
# OUTPUT of failure
simpsons=ARRAY(0x1ab2da0)
jetsones=ARRAY(0x1ab56f4)
flinstones=ARRAY(0x1ab558c)
=cut
## One standard means of printing %hoa--how can I possibly
## code something such as this for an arbitrarily complex
## data structure?
print "$_ @{ $hoa{$_} }\n" for (sort keys %hoa);
Thanks in advance to anyone who offers any advice on how to solve the
above problem.
JR