看起來我應該可以使用map來完成此任務,但實際的細節並不適用於我。perl:使用地圖獲取哈希值
我有一個數組中的字符串列表,並且零或其中一個可能有一個哈希值。
所以不是這樣做的:
foreach $str (@strings) {
$val = $hash{$str} if $hash{$str};
}
可以這樣用一行代碼使用的地圖取代?
看起來我應該可以使用map來完成此任務,但實際的細節並不適用於我。perl:使用地圖獲取哈希值
我有一個數組中的字符串列表,並且零或其中一個可能有一個哈希值。
所以不是這樣做的:
foreach $str (@strings) {
$val = $hash{$str} if $hash{$str};
}
可以這樣用一行代碼使用的地圖取代?
當然,這會是:
map { $val = $hash{$_} } @strings;
也就是說,@strings
每個值在$_
依次設置(而不是$str
在你的foreach)。
當然,這並沒有太大的作用,因爲你在循環中沒有做任何值$val
,我們也沒有捕獲到map
返回的列表。
如果你只是想生成值的列表,這會是:
@values = map { $hash{$_} } @strings;
但它更簡潔使用散列切片:
@values = @hash{@strings};
編輯:由於尖頭在評論中,如果@strings
可能包含的值不是你hash中的鍵值,那麼@values
將在這些位置得到undefs。如果這不是您想要的,請參閱Hynek's answer獲取解決方案。
map { defined $hash{$_} && ($val = $hash{$_})} @strings;
@values = grep { $_ } @hash{@strings};
佔的事實,你只需要真正值。
更改爲
@values = grep { defined } @hash{@strings};
,如果你想跳過未定義的值。
我用來做什麼的這樣:
@values = map { exists $hash{$_} ? $hash{$_} :() } @strings;
,但我看不出有什麼不妥這樣
push @values, $hash{$_} for grep exists $hash{$_}, @strings;
或
@values = @hash{grep exists $hash{$_}, @strings};
+1但是,請記住'@ values'可能仍包含'undef's。這是否理想取決於上下文。 – 2009-11-10 23:10:36
+1,但只需使用散列片並完成它。 – 2009-11-10 19:40:45
散列片將使數組具有undefs,其中字符串不在散列表中。 – 2009-11-10 20:56:52
@Hynek:好的一點,你的答案+1,處理這種情況。 – 2009-11-10 23:00:06