DataStructure::RecursivelyTransform?
bduggan
created: 2006-05-02 11:50:51
Hi All,

I have an arbitrarily complex data structure, and I'd like to change the values in all the hashrefs in it when the corresponding key matches a certain pattern. The boring subroutine below does the trick, but I feel like there must be something existing on CPAN which I haven't been able to find, that handles things like this more generically (and cleanly/efficiently?). Can anyone point me towards such a module? Thanks
sub change_hash_values {
    my $sub   = shift;
    my $h     = shift;
    my $match = shift;
    return unless ref($h);
    for ( ref($h) ) {
        /HASH/ and do {
            for ( keys %$h ){
                change_hash_values ( $sub, $h->{$_}, $match );
                $h->{$_} = $sub->( $h->{$_} ) if /$match/;
            }
        };
        /ARRAY/ and do {
            change_hash_values ( $sub, $_, $match ) for @$h;
        };
    }
}

my $z = {
        foo => [qw(a b c)],
        bar => [ 'a' , { changeme => 'oz' } ],
        baz => 'z'
};


change_hash_values( sub { $_[0]=~s/z/x/g; return $_[0]; },$z, qr/change/);



# Turns oz into ox

Re: DataStructure::RecursivelyTransform?
created: 2006-05-02 13:05:51

Take a look at [cpan://Data::Rmap]. Something like this should do the trick.

use Data::Rmap qw[ rmap_hash ];

rmap_hash{
    for my $key ( keys %{ $_ } ) {
        next unless $key eq 'Target key value';
        $_->{ $key } =~ $someRegex;
    }       
} $refToArbitraryStructure;

Whether that is an easier than what you have is your decision. More efficient? Benchmark it :)


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

perlmonks.org content © perlmonks.org and bduggan, BrowserUk

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03