Home > Net >  Check data structure and disregard if hash or array
Check data structure and disregard if hash or array

Time:09-17

I have a bunch of Hashes inside of an array. When checking my keys and values I get the expected output except for some special cases as they refer to more Arrays/Hashes.

Think of something like this:

@AoH = ( { 'husband' => "homer", 'wife' => "marge" },
         { 'people' => [{'Bob'=> 24, 'Lukas'=> 37}] },
         { 'vegetables' => { 'tomato' => "red", 'carrot' => "orange"} }); 

My function iterates through the array and displays my keys and values as in the following:

 sub function(...){    
    print "$key => $value\n";
 }

husband => homer
wife => marge
people => ARRAY(0x6b0d80)
Bob => 24
Lukas => 37
vegetables => HASH(0x2570d38)
tomato => red
carrot => orange

Now I want to access my keys and values, but when getting something like ARRAY or HASH as value, I want to disregard that hash and not print it.

Is there some kind of way to only access Values with type scalar?

So far I tried this:

if ($value eq 'ARRAY') {
}
elsif ($value eq ref {}) {
}
else {
print "$key => $value\n";
}

But, it ends up printing exactly the same as above and does not disregard the other data structures.

CodePudding user response:

For an arbitrary data structure like yours, you can use Data::Traverse:

use warnings;
use strict;
use Data::Traverse qw(traverse);

my @AoH = ( { 'husband' => "homer", 'wife' => "marge" },
            { 'people' => [{'Bob'=> 24, 'Lukas'=> 37}] },
            { 'vegetables' => { 'tomato' => "red", 'carrot' => "orange"} }); 

traverse { print "$a => $b\n" if /HASH/ } \@AoH;

Output:

wife => marge
husband => homer
Bob => 24
Lukas => 37
carrot => orange
tomato => red

CodePudding user response:

Following demo code does not utilize external modules, provided for educational purpose.

use strict;
use warnings;
use feature 'say';

my @AoH = (  { 'husband' => "homer", 'wife' => "marge" },
             { 'people' => [{'Bob'=> 24, 'Lukas'=> 37}] },
             { 'vegetables' => { 'tomato' => "red", 'carrot' => "orange"} });
             
drill_in( \@AoH );

sub drill_in {
    my $data = shift;
    
    if( ref $data eq 'ARRAY' ) {
        drill_in($_) for @$data;
    } elsif ( ref $data eq 'HASH' ) {
        while( my($k, $v ) = each %{$data} ) {
            (ref $v eq 'ARRAY' or  ref $v eq 'HASH') ? drill_in($v) : say "$k => $v";
        }
    }
}

Output

husband => homer
wife => marge
Lukas => 37
Bob => 24
tomato => red
carrot => orange
  • Related