How do you remove undefined keys from a hash?
Trying to use map and grep to figure this out, any idea whats wrong? I keep getting 开发者_如何学Pythona Can't use string ("10") as a HASH ref while "strict refs" error when I try to print the values of the new hash
sub scrub_hash{
my($self,$hash_ref) = @_;
my $scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
print STDERR "[scrub]". $_."\n" for values %{$scrubbed_hash};
}
used here ...
my $params_hash = $cgi->Vars();
my $scrubbed = $self->scrub_empty_params($params_hash) if $self->is_hash($params_hash);
in this case the params that are undefined when a form is submitted via post still show up as key1=&key2= so scrub takes em off
In this line here:
my $scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
You are assigning a list from map
into the scalar $scrubbed_hash
. map
in scalar context will return the number of elements in the list (10).
Rather than assigning to a scalar, assign to a plural hash:
sub scrub_hash{
my($self,$hash_ref) = @_;
my %scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};
print STDERR "[scrub]". $_."\n" for values %scrubbed_hash;
}
If you really wanted to use a scalar for $scrubbed_hash
you will need to wrap the map statement with {map {...} args}
which will construct an anonymous hash out of the list.
To filter out the elements in place, you could use the delete
function:
my %hash = (foo => 1, bar => undef, baz => 2);
defined $hash{$_} or delete $hash{$_} for keys %hash;
print join ', ' => keys %hash; # foo, baz
per the update:
The scrub_empty_params
method should look something like this:
sub scrub_empty_params {
my ($self, $hash) = @_;
{map {defined $$hash{$_} ? ($_ => $$hash{$_}) : ()} keys %$hash}
}
If that is not working for you, then it may be that your values are defined, but have a length of 0.
sub scrub_empty_params {
my ($self, $hash) = @_;
{map {(defined $$hash{$_} and length $$hash{$_}) ? ($_ => $$hash{$_}) : ()} keys %$hash}
}
You might want to remove a bit of boiler plate from your API by creating a different ->Vars()
method that returns a filtered hash:
sub clean_vars {
my ($self) = @_;
$self->scrub_empty_params($self->Vars)
}
Try this:
my %scrubbed_hash = map { $_ => $hash_ref->{ $_ } } grep { defined $hash_ref->{$_} } keys %{$hash_ref};
精彩评论