Goal: Remove a particular value from an array
I have written a script, and it works fine, but I am not happy the way I have written it. So I am curious to know is there a better way to write it. Please consider the below use case:
I have a nested hash/hash/array...like below. I need to remove any array values which has local
in their name:
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $hash = { esx1 =>
{ cluster => "clu1",
fd => "fd1",
ds => [
'ds1',
'ds2',
'localds',
],
},
esx2 =>
{ cluster => "clu2",
fd => "fd2",
ds => [
'ds3',
'ds4',
'dslocal',
],
},
};
foreach my $a ( keys %$hash )
{
foreach ( 0..$#{ $hash->{$a}->{ds} } )
{
delete $hash->{$a}->{ds}->[$_] if $hash->{$a}->{ds}->[$_] =~ /local/i;
@{ $hash->{$a}->{ds} } = grep defined, @{ $hash->{$a}->{ds} };
}
}
print Dumper ($hash);
so the script deletes the "localds
" and "dslocal
" and keeps everything else intact.
foreach ( 0..$#{$hash->{$a}->{ds} } )
loop?grep
line above, the resultant array has the value containing local
deleted, but it is replaced by undef
. Why is this happening?It isn't necessary to first iterate through the array and delete elements and then look for "not-deleted" nodes (side note: this grep
should be outside the loop).
You can look for good nodes from the very start! Replace the entire loop with:
foreach my $a ( keys %$hash )
{
@{ $hash->{$a}->{ds} } = grep { !/local/i } @{ $hash->{$a}->{ds} };
}