Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out if a Perl hash is multidimensional?

Tags:

hash

perl

Assuming I have a hash like this:

$hash_ref = {

  'hashes' => {
    'h1' => { 'klf' => '1', 'moomooland' => '1' },
    'h2' => { 'klf' => '2', 'moomooland' => '2' },
    'h3' => { 'klf' => '3', 'moomooland' => '3' }
  },

  'keys' => {
    'k1' => 'key1',
    'k2' => 'key2',
    'k3' => 'key3'
  }

}

How could I find out, as easy as possible, that hashes contains 3 more hashes, while keys contains 3 key/value pairs?

ref will return HASH for both of them, and I am not sure if it is possible to maybe find out the depth of these hashes.

Thanks :)

like image 625
sentinel Avatar asked Aug 26 '10 06:08

sentinel


3 Answers

If you just need to know if a hash is multi-dimensional, you can iterate over its values and stop if a reference is found:

my $is_multi_dimensional = 0;

for my $value (values %$hash_ref) {
    if ('HASH' eq ref $value) {
        $is_multi_dimensional = 1;
        last;
    }
}

or you can use the each() function:

while (my (undef, $value) = each %$hash_ref) {
    if ('HASH' eq ref $value) {
        $is_multi_dimensional = 1;
        last;
    }
}
like image 194
Eugene Yarmash Avatar answered Sep 28 '22 19:09

Eugene Yarmash


You can also first and grep for this:

use List::Util 'first';
say 'is multi-dimensional' if first { ref } values %$hash_ref;

# explicitly check for HASH ref this time
my $how_many_md_hashes = grep { 'HASH' eq ref } values %$hash_ref;

NB. first (part of List::Util core module) short circuits so is ideal for conditionals and is probably the fastest of all possible options.

/I3az/

like image 31
draegtun Avatar answered Sep 28 '22 19:09

draegtun


You can try this one to know the depth of Perl hash:

#!/usr/bin/perl
use strict;
my $hash_ref = {

  'hashes' => {
    'h1' => { 'klf' => '1', 'moomooland' => '1' },
    'h2' => { 'klf' => '2', 'moomooland' => '2' },
    'h3' => { 'klf' => '3', 'moomooland' => '3' }
  },

  'keys' => {
    'k1' => 'key1',
    'k2' => 'key2',
    'k3' => 'key3'
  }

};
print_nested_hash($hash_ref, 0);

sub print_nested_hash {
    my $hash_ref = shift;
    my $depth = shift;
    foreach my $key (sort keys %{$hash_ref}) {
        print '    ' x $depth, $key, "\n";

        if (ref($hash_ref->{$key}) eq "HASH") {
            print_nested_hash($hash_ref->{$key}, $depth+1);
        }
    }
} 

OUTPUT:

hashes
    h1
        klf
        moomooland
    h2
        klf
        moomooland
    h3
        klf
        moomooland
keys
    k1
    k2
    k3
like image 21
Nikhil Jain Avatar answered Sep 28 '22 20:09

Nikhil Jain