RecursionBane has asked for the wisdom of the Perl Monks concerning the following question:
Greetings, Monks!
I'm attempting to write a subroutine to perform regexp-based string substitution on the deepest elements of a complex, non-deterministic hash structure (i.e., it could be a HoAoHoA or a HoHoA or a HoA, or any other combination, to any depth). Note that we have no control over this structure. This operation will be performed infrequently enough that I've optimized for readability rather than runtime.
This is the (untested!) code I'm attempting; please let me know if there's an easier way to do this:
I've looked at Hash::Util, but it didn't seem to handle N-deep structures.
Update: One thing I've just thought of is stringifying the entire structure, performing the search and replace, then converting the structure back. Would this be easier/more efficient? Is Data::Dumper the way to go for this?
Any ideas? Thanks in advance!
~RecursionBane
I'm attempting to write a subroutine to perform regexp-based string substitution on the deepest elements of a complex, non-deterministic hash structure (i.e., it could be a HoAoHoA or a HoHoA or a HoA, or any other combination, to any depth). Note that we have no control over this structure. This operation will be performed infrequently enough that I've optimized for readability rather than runtime.
This is the (untested!) code I'm attempting; please let me know if there's an easier way to do this:
sub search_and_replace_in_hash { # Given a hash, perform a perl regexp operation on every value, re +gardless of how deep the hash is # Usage: search_and_replace_in_hash <\%hash> <expression> # Returns: New hash reference with replacement performed on deepes +t elements my %hash = %{shift()}; my $op = shift(); foreach my $key (sort keys %hash) { if ( reftype( $hash{$key} ) eq "HASH" ) { if (scalar( keys( %{$hash{$key}} ) ) > 0) { %hash = %{search_and_replace_in_hash( $hash{$key}, $op + )}; } next; } if ( reftype( $hash{$key} ) eq "ARRAY" ) { if (scalar( @{$hash{$key}} ) > 0) { foreach my $list_element (@{$hash{$key}}) { if (reftype($list_element) eq "HASH") { %hash = %{search_and_replace_in_hash( $hash{$k +ey}{$list_element}, $op )}; next; } } } else { next; } } # If you get here, you're a scalar %hash{$key} =~ $op; } return \%hash; }
I've looked at Hash::Util, but it didn't seem to handle N-deep structures.
Update: One thing I've just thought of is stringifying the entire structure, performing the search and replace, then converting the structure back. Would this be easier/more efficient? Is Data::Dumper the way to go for this?
Any ideas? Thanks in advance!
~RecursionBane
|
---|
Back to
Seekers of Perl Wisdom