Question

I want to print a hash of hashes of hashes (with an indefinable depth) as CSV.

Imagine that I have a structure of foos, bars, cars, ... where the keys of the deepest hash are pointing to a numeric scalar.

I want to print this structure to look like this:

foo1;bar1;car1;345
foo1;bar1;car2;25347
foo1;bar2;car1;23
foo2;bar1;car1;863
......
......

Does anybody know how to do this, when you're not aware of the depth of the hash-structure (there also could be additional mars and wars and so on)?

What have I tried so far?

sub print_csv {
    my $subj = shift;
    if ( ref($subj) eq "HASH" ) {
        for ( keys $subj ) {
            print "$_;";
            print_csv( $subj->{$_} );
        }
    }
    else {
        print "$subj\n";
    }
}

This is my general idea, but the keys of the hashes won't be repeated after the first one.

Thanks in advance!!!

Edit
I'm already using perl 5.14. My Problem is, that the keys of the hashes won't be repeated after they first appeared. My current output looks like this:

foo1;bar1;4
foo2;bar2;12060
bar3;24
bar1;152
foo3;bar3;1
bar1;815

foo2 has 3 bars (bar1, bar2, bar3), but it's name "foo2" isn't repeated in lines 3 and 4. It's the same with foo3. It has two bars (bar1 and bar3) but it's name "foo3" is missing in line 6.

Was it helpful?

Solution

Got it now, I think this is what you want:

sub print_csv {
    my $subj = shift;
    my $prefix = shift || "";
    if ( ref($subj) eq "HASH" ) {
        for ( keys %$subj ) {
            print_csv( $subj->{$_}, $prefix ."$_;");
        }
    }
    else {
        print "$prefix$subj\n";
    }
}

Data:

my %hash = ();
my %hash2 = ();
my %hash3 = ();

$hash3{"test3Key"}="test5";
$hash2{"test2Key"}=\%hash3;
$hash2{"test2Key2"}="test2Key2Value";
$hash{"testSimpleKey"} = "test2";
$hash{"testHashRefKey"}=\%hash2;

Results:

testSimpleKey;test2
testHashRefKey;test2Key;test3Key;test5
testHashRefKey;test2Key2;test2Key2Value
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top