2009-11-10 129 views
1

看起來我應該可以使用map來完成此任務,但實際的細節並不適用於我。perl:使用地圖獲取哈希值

我有一個數組中的字符串列表,並且零或其中一個可能有一個哈希值。

所以不是這樣做的:

foreach $str (@strings) { 
    $val = $hash{$str} if $hash{$str}; 
} 

可以這樣用一行代碼使用的地圖取代?

回答

4

當然,這會是:

map { $val = $hash{$_} } @strings; 

也就是說,@strings每個值在$_依次設置(而不是$str在你的foreach)。

當然,這並沒有太大的作用,因爲你在循環中沒有做任何值$val,我們也沒有捕獲到map返回的列表。

如果你只是想生成值的列表,這會是:

@values = map { $hash{$_} } @strings; 

但它更簡潔使用散列切片:

@values = @hash{@strings}; 

編輯:由於尖頭在評論中,如果@strings可能包含的值不是你hash中的鍵值,那麼@values將在這些位置得到undefs。如果這不是您想要的,請參閱Hynek's answer獲取解決方案。

+0

+1,但只需使用散列片並完成它。 – 2009-11-10 19:40:45

+1

散列片將使數組具有undefs,其中字符串不在散列表中。 – 2009-11-10 20:56:52

+0

@Hynek:好的一點,你的答案+1,處理這種情況。 – 2009-11-10 23:00:06

1
map { defined $hash{$_} && ($val = $hash{$_})} @strings; 
6
@values = grep { $_ } @hash{@strings}; 

佔的事實,你只需要真正值。

更改爲

@values = grep { defined } @hash{@strings}; 

,如果你想跳過未定義的值。

3

我用來做什麼的這樣:

@values = map { exists $hash{$_} ? $hash{$_} :() } @strings; 

,但我看不出有什麼不妥這樣

push @values, $hash{$_} for grep exists $hash{$_}, @strings; 

@values = @hash{grep exists $hash{$_}, @strings}; 
+0

+1但是,請記住'@ values'可能仍包含'undef's。這是否理想取決於上下文。 – 2009-11-10 23:10:36