2013-05-31 46 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。 –