开发者

How do you remove undefined keys from a hash?

开发者 https://www.devze.com 2023-04-11 14:46 出处:网络
Trying to use map and grep to figure this out, any idea whats wrong? I keep getting 开发者_如何学Pythona

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};   
0

精彩评论

暂无评论...
验证码 换一张
取 消