I want to delete an element of a hash(of any depth) which has the first key as $key[0], the second key as $key[1] etc, until @key is finished.
For example, if @key=(23,56,78) then i want to manipulate $hash{23}{56}{78}.
I don't know beforehand how many elements @key has.
I have been trying to use the following:
my %the_path;
my $temp=\%the_path;
for(my $cline=0;$cline<=$#keys;$cline++){
my $cfolder=$keys[$cline];
$temp->{$cfolder}={};
$temp=$temp->{$cfolder};
}
But, I'm not sure how to manipulate the element at here. How do I do that?
Data::Diver exists for exactly this purpose.
my $last_hash = Data::Diver::Dive( \%hash, @keys[0..$#keys-1] );
if ($last_hash) { delete $last_hash->{ $keys[-1] } }
Here is an example with recursion:
use strict;
use warnings;
my $hash = { foo => { here => 'there', bar => { baz => 100 } } };
## mutates input
sub delete_hash {
my ( $hash, $keys ) = @_;
my $key = shift @$keys;
die "Stopped recursing $key doesn't exist"
unless exists $hash->{$key}
;
scalar @$keys
? delete_hash( $hash->{$key}, $keys )
: delete $hash->{$key}
;
}
delete_hash( $hash, [qw/foo bar/] );
use XXX;
YYY $hash;
The stack does grow and function calls have a price. You can aparently mitigate that with perl's version of TCO with this code:
if (scalar @$keys) {
@_=($hash->{$key}, $keys);
goto &delete_hash;
}
else {
delete $hash->{$key}
}
And, it should also noted that none of this code prunes the tree: if you delete [qw/foo bar baz/] then bar will be an empty hash ref.
foo:
bar: {}
here: there
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With