chanakya has asked for the wisdom of the Perl Monks concerning the following question:
Greetings
I have a complex data structure as given below
@data_array_ref = [
mykey1 => {firstkey => 'firstvalue', secondkey => 'secondval' }
mykey2 => {ninza => 'turtle', 'Hurricane' => 'Dennis'}
mykey3 => [ [one,two, three]
mykey4 => [ [4, 5, three] [6, 7, four] [8, 9, five] ]
]
I've tried to get the output as given below from the above data structure but I'm not successful. Can someone throw some light about the same.
mykey1 => firstval, secondval
mykey2 => turtle, Dennis
mykey3 => one, two, three
mykey4 = 4, 5, three, 6, 7, four, 8, 9, five
Thank you in advance
Re: Parsing complex data
by Limbic~Region (Chancellor) on Jul 15, 2005 at 15:13 UTC
|
chanakya,
Since you have omitted details of your requirements I am going to guess that you know you have an AoHo(H or A) and that you want the keys of the second level H and corresponding values of the (H or A) regardless of which it is.
for ( @$data } {
print "$_ =>";
if ( ref $_ eq 'ARRAY' ) {
print join ", ", @$_;
}
else {
print join ", ", sort values %$_;
}
print "\n";
}
Note: You may have to modify this a bit to get a specific order with your hashes if the simple sort I provided isn't satisfactory. You will also have to modify the depth of ref depending on how many levels deep you need to go. IOW - this isn't fully working code but an idea of how to get started.
Update:Data::Dump::Streamer and/or Data::Dumper may also be of some help. As socketdave points out, your data structure is missing commas and unbalanced and it is hard to say for sure what you want without some more specifics
| [reply] [d/l] |
|
The structure of your input data also seems pretty hosed to me, but I could be missing something... shouldn't it be something closer to:
my $data = [
mykey1 => { 'firstkey' => 'firstvalue', 'secondkey' => 'secondval'
+ },
mykey2 => { 'ninza' => 'turtle', 'Hurricane' => 'Dennis' },
+
mykey3 => [ [ 'one', 'two', 'three' ] ],
mykey4 => [ [ 4, 5, 'three' ], [ 6, 7, 'four' ], [ 8, 9, 'five' ]
+],
];
| [reply] [d/l] |
|
output
======
mykey1 =>
HASH(0x1abefc0) =>firstvalue, secondval
mykey2 =>
HASH(0x1abf0a4) =>Dennis, turtle
mykey3 =>
ARRAY(0x1ab5148) =>ARRAY(0x1ab50d0)
mykey4 =>
ARRAY(0x1ab52f8) =>ARRAY(0x1ab5190), ARRAY(0x1ab5208), ARRAY(0x1ab5280
+)
My solution:
$data_array_ref = [
mykey1 => {firstkey => 'firstvalue', secondkey => 'secondval' },
mykey2 => {ninza => 'turtle', 'Hurricane' => 'Dennis'},
mykey3 => [ ['one', 'two', 'three'] ],
mykey4 => [ [4, 5, 'three'], [6, 7, 'four'], [8, 9, 'five'] ],
];
my $i = 0;
while ($i < @$data_array_ref) {
my $key = $data_array_ref->[$i++];
my $val = $data_array_ref->[$i++];
print "$key => ";
if (ref($val) eq 'HASH') {
print join ', ',
values %$val;
}
else
{
print join ', ',
map { @$_ }
@$val
}
print "\n";
}
__END__
output
======
mykey1 => firstvalue, secondval
mykey2 => turtle, Dennis
mykey3 => one, two, three
mykey4 => 4, 5, three, 6, 7, four, 8, 9, five
It be somewhat easier if your topmost data structure was a hash, not an array.
map { @$_ } @$_ flattens a ref to an array of arrays of scalars, as opposed to @$_ which only flattens a ref to an array of scalars.
| [reply] [d/l] [select] |
|
| [reply] |
Re: Parsing complex data
by tcf03 (Deacon) on Jul 15, 2005 at 15:26 UTC
|
| [reply] |
Re: Parsing complex data
by themage (Friar) on Jul 15, 2005 at 15:57 UTC
|
Hi,
I'ld do it like this:
#!/usr/bin/perl -w
use strict;
sub printstruct {
my $struct=shift;
my $main=shift||0;
my $ret=$main?"\n":" ";
my $item;
if (ref $struct eq "ARRAY") {
for $item (sort @$struct) {
printstruct($item);
}
} elsif (ref $struct eq "HASH") {
for $item (sort keys %$struct) {
print $item," " if $main;
printstruct($struct->{$item});
print $ret;
}
} else {
print $struct,$ret;
}
}
my $struct={
mykey1 => { 'firstkey' => 'firstvalue', 'secondkey' => 'secondval'
+ },
mykey2 => { 'ninza' => 'turtle', 'Hurricane' => 'Dennis' },
mykey3 => [ [ 'one', 'two', 'three' ] ],
mykey4 => [ [ 4, 5, 'three' ], [ 6, 7, 'four' ], [ 8, 9, 'five' ]
+],
};
printstruct($struct,1);
Note that I was unsure which the correct data struct was, so I made some changes in it as you can see. This would work for any struct with the three basic data types.
| [reply] [d/l] |
Re: Parsing complex data
by sh1tn (Priest) on Jul 15, 2005 at 15:56 UTC
|
my @data = [
mykey1 => {firstkey => 'firstvalue', secondkey => 'secondval' },
mykey2 => {ninza => 'turtle', 'Hurricane' => 'Dennis'},
mykey3 => [ [one,two, three] ],
mykey4 => [ [4, 5, three], [6, 7, four], [8, 9, five] ],
];
for( @{$data[0]} ){
ref or print "$_ => " and next;
ref eq 'SCALAR' and print $$_ and next;
ref eq 'HASH' and print join( ',', values %$_ ), $/;
ref eq 'ARRAY' and do {
for( @{$_} ){
print join( ',', split( '\s', "@$_ " ))
}
print $/
};
}
| [reply] [d/l] |
|
|