Как удалить неопределенные ключи из хеша? - PullRequest
1 голос
/ 06 октября 2011

Пытаясь использовать map и grep, чтобы понять это, есть идеи, что не так? Я продолжаю получать Невозможно использовать строку ("10") в качестве ссылки HASH, в то время как ошибка "strict refs" при попытке напечатать значения нового хеша

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

используется здесь ...

my $params_hash = $cgi->Vars();
my $scrubbed = $self->scrub_empty_params($params_hash) if $self->is_hash($params_hash);

в этом случае параметры, которые не определены при отправке формы по почте, по-прежнему отображаются как key1 = & key2 =, поэтому scrub снимает их

Ответы [ 2 ]

6 голосов
/ 06 октября 2011

В этой строке здесь:

my $scrubbed_hash = map { defined $hash_ref->{$_} ? ($_ => $hash_ref->{$_}) : () } keys %{$hash_ref};   

Вы назначаете список из map в скаляр $scrubbed_hash.map в скалярном контексте вернет количество элементов в списке (10).

Вместо присвоения скаляру присвойте множественному хешу:

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

Если вы действительноЕсли вы хотите использовать скаляр для $scrubbed_hash, вам нужно будет обернуть оператор map в {map {...} args}, который создаст анонимный хеш из списка.

Чтобы отфильтровать элементы на месте, вы можете использоватьdelete функция:

my %hash = (foo => 1, bar => undef, baz => 2);

defined $hash{$_} or delete $hash{$_} for keys %hash;

print join ', ' => keys %hash;  # foo, baz

за обновление:

Метод scrub_empty_params должен выглядеть примерно так:

sub scrub_empty_params {
    my ($self, $hash) = @_;
    {map {defined $$hash{$_} ? ($_ => $$hash{$_}) : ()} keys %$hash}
}

Если этоне работает для вас, тогда может быть, что ваши значения определены, но имеют длину 0.

sub scrub_empty_params {
    my ($self, $hash) = @_;
    {map {(defined $$hash{$_} and length $$hash{$_}) ? ($_ => $$hash{$_}) : ()} keys %$hash}
}

Возможно, вы захотите удалить немного котельной из вашего API, создав другой ->Vars() метод, который возвращает отфильтрованный хеш:

sub clean_vars {
    my ($self) = @_;
    $self->scrub_empty_params($self->Vars)
}
2 голосов
/ 06 октября 2011

Попробуйте это:

    my %scrubbed_hash = map { $_ => $hash_ref->{ $_ } } grep { defined $hash_ref->{$_} } keys %{$hash_ref};   
...