Traversing a multi-dimensional hash in Perl

后端 未结 8 1953
后悔当初
后悔当初 2021-01-03 04:02

If you have a hash (or reference to a hash) in perl with many dimensions and you want to iterate across all values, what\'s the best way to do it. In other words, if we hav

8条回答
  •  既然无缘
    2021-01-03 04:11

    It's easy enough if all you want to do is operate on values, but if you want to operate on keys, you need specifications of how levels will be recoverable.

    a. For instance, you could specify keys as "$level1_key.$level2_key.$level3_key"--or any separator, representing the levels.

    b. Or you could have a list of keys.

    I recommend the latter.

    • Level can be understood by @$key_stack

    • and the most local key is $key_stack->[-1].

    • The path can be reconstructed by: join( '.', @$key\_stack )

    Code:

    use constant EMPTY_ARRAY => [];
    use strict;    
    use Scalar::Util qw;
    
    sub deep_keys (\%) { 
        sub deeper_keys { 
            my ( $key_ref, $hash_ref ) = @_;
            return [ $key_ref, $hash_ref ] if reftype( $hash_ref ) ne 'HASH';
            my @results;
    
            while ( my ( $key, $value ) = each %$hash_ref ) { 
                my $k = [ @{ $key_ref || EMPTY_ARRAY }, $key ];
                push @results, deeper_keys( $k, $value );
            }
            return @results;
        }
    
        return deeper_keys( undef, shift );
    }
    
    foreach my $kv_pair ( deep_keys %$f ) { 
        my ( $key_stack, $value ) = @_;
        ...
    }
    

    This has been tested in Perl 5.10.

提交回复
热议问题