1,105,226 Community Members

how to find the depth of Perl hash which has no consistent structure

Member Avatar
sugumarclick
Light Poster
42 posts since Jun 2009
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Hi Daniwebbers,
can someone help me How to figure out the depth of a dynamic hash (hash of hashes) in perl. If it has consistent structure, we can traverse through while/foreach and find out the depth. Could anyone point me the right and best way to figure it out.

my %hash1 = (

    name => {
            first => "John",
            last => "branham",
            middle => "visa",
        },
    address => {
            park => "cubbon",
            doorno => "4/6",
            other => {
                division => "division",
                city => "Cincinati",
                state => "Ohio",
                country => {
                    cont => "NA",
                    code => "USA",
                    pin => "51123",

                },
                district => "district",

                }

    },
    status => "unmarried"
);

%hash2 might or might not have the structure.. for instance.. address might be blank.
Inshort am in need of a subroutine which could take an hash as an argument and return (highest) depth of the hash above example is 5 . $href->{"hash1"}->{"address"}->{other}->{country}->{code}.

I tried with recursive funtion. but with no success..
Any help would be highly appreciated.. Thanks

Member Avatar
2teez
Posting Whiz in Training
221 posts since Apr 2012
Reputation Points: 40 [?]
Q&As Helped to Solve: 38 [?]
Skill Endorsements: 0 [?]
 
1
 

Hi,
Please sorry, this reply is coming this later. It's better later than never... :)

I think basically, all you needed is a recursive subroutine. Using ref to check the value dataset.

Something like this:

sub dump_data {
    my $ref = shift;

    for ( keys %{$ref} ) {
        print $_, '=>';
        if ( ref $ref->{$_} eq 'HASH' ) {
            dump_data( $ref->{$_} );  ## sub called itself
        }
        else { print $ref->{$_}, $/ }
    }
}

It would print all your keys and values out. However, you can twist that a bit to get you what you wanted. Like so:

#!/usr/bin/perl
use warnings;
use strict;

my %hash1 = (

    name => {
        first  => "John",
        last   => "branham",
        middle => "visa",
    },
    address => {
        park   => "cubbon",
        doorno => "4/6",
        other  => {
            division => "division",
            city     => "Cincinati",
            state    => "Ohio",
            country  => {
                cont => "NA",
                code => "USA",
                pin  => "51123",

            },
            district => "district",

          }

    },
    status => "unmarried"
);

 my $start_level = 0;

dump_data( \%hash1, $start_level );

sub dump_data {
    my ( $ref, $level ) = @_;

    die "You can only pass an HASH reference data"
      unless ref $ref eq 'HASH';

    for ( keys %{$ref} ) {
        print $/, 'Level ', $level, "\t" x $level, $_, '=>';
        if ( ref $ref->{$_} eq 'HASH' ) {
            dump_data( $ref->{$_}, ++$level );    ## sub called itself
        }
        else { print $ref->{$_}, $/ }
    }
}

It's print out all the keys, values and the Levels of each. You are free to modify this, if it doesn't server your purpose.

Member Avatar
sugumarclick
Light Poster
42 posts since Jun 2009
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

absolutely stunning. This was exactly I was looking for.

Question Answered as of 7 Months Ago by 2teez
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: