Search code examples
arraysperldata-structureshashmapscalar

Check data structure and disregard if hash or array


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.


Solution

  • 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