2013-05-31 45 views
1

我希望在只有当我有一个定义的值来分配散列创建一个键/值对。只有创造Perl的哈希键/值对当值定义

我目前这样做:

$hash{key1} = $val1 if defined $val1; 

这是好的 - 但是当$val1是复杂的可以成为恼人。有没有一种方法,我可以整齐地得到相同的结果,而不必说$val1两次?下面的测试脚本可能有助于澄清我试图达到的目标。

use strict; 
use warnings; 
use Test::More tests => 1; 

my %hash; 
my $val1 = undef; # Explicitly undef 
my $val2 = 10; 
$hash{key1} = $val1 if defined $val1; 
$hash{key2} = $val2 if defined $val2; 
my %expected = ('key2', 10); 
is_deeply(\%hash, \%expected, 'Hashes compare'); 

回答

1

写子程序。

set(\%hash, $key1, $val1); 
set(\&hash, $key2, $val2); 

sub set { 
    my $hash = shift; 
    my $key = shift; 
    my $val = shift; 

    $hash->{$key} = $val if defined $val; 
} 
+0

谢谢安迪 - 我将回答的问题提到了这个问题上,因为它不仅在功能上等同 - 它很整洁,清晰 - 我一直在寻找。 –

3

如果你有很多这样的价值观来检查,你可以使用grep /列表:

use strict; 
use warnings; 
my %hash; 
my $val1 = undef;  
my $val2 = 10; 
$hash{$_->[0]} = $_->[1] for grep { defined $_->[1] } 
    ['key1', $val1], ['key2', $val2]; 

或者你可以盲目地填充它后过滤哈希:

$hash{key1} = $val1; 
$hash{key2} = $val2; 
%hash = map { $_, $hash{$_} } grep { defined $hash{$_} } keys %hash; 
+0

谢谢@perreal - 大加赞赏。这在功能上当然是等同的,并且符合仅值一次的要求。我可能不会在我的语境中使用,因为我在减少重复中获得的可读性受损。 –

+1

我已经编辑你的代码到grep为'{$定义_-> [1]}',而不是仅仅'{$ _-> [1]'。正如所写,它将排除值为0的键,空字符串或字符串“0”,因为这些值被认为是“false”。 –

+0

理想情况下,我希望沿着'$ hash {key} =行定义了一些东西,如果定义了$ val;' - 那就是一些像尾随一样的流控制语句,如果它也可以用作RValue。但是,因为它看起来并不像我有任何更好的方式,所以我将这个回应标记为答案。谢谢Dave和perreal。 –