2014-08-27 41 views
1

我要評論的原始問題,但我還沒有這樣做的聲譽呢......更新紅寶石中的哈希值澄清

我也想知道如何輕鬆更新所有的值散列,或者是否有某種等效的.map!散列方法。有人把了這個優雅的解決方案:

hash.update(hash){|key,v1| expresion} 

在這個問題上: Ruby: What is the easiest method to update Hash values?

我的問題是如何塊知道遍歷哈希每個元素?例如,我不得不打電話。每一個散列來訪問每個元素通常這樣爲什麼不是這樣的:

hash.update(hash.each) do |key ,value| 
    value+=1 
end 

與{塊|鍵,值|表達式}我正在訪問每個單獨的散列元素,但我不必明確告訴系統呢?爲什麼不?非常感謝你。

回答

0

Hash#updateHash#merge!的別名,它更具描述性。

當調用與塊的方法中,將發生以下情況(來自文檔的摘錄):

如果[A]爲指定塊,[...]的每個重複的鍵的值是 確定通過調用塊與鍵[...]

所以,上面的代碼是這樣的:

哈希值合併本身,併爲每個重複鍵塊被調用。當我們將散列與自身合併時,每個新添加的鍵都是重複的,因此塊被調用。結果是散列中的每個值都被替換爲expresion

+0

'expresion'是對問題中原始代碼的引用(它已經有一個錯字)。 – koffeinfrei 2014-08-27 21:20:31

0

Hash#update將散列作爲第一個參數,將可選塊作爲第二個參數。如果省略第二個參數,則該方法將在內部循環所提供散列中的每個鍵值對,並將它們合併到原始散列中。

如果提供了塊(第二個參數),則該方法執行完全相同的操作。它循環遍歷所提供的散列中的每個鍵值並將其合併。唯一的區別是發現衝突的位置(原始散列已經具有特定鍵的條目)。在這種情況下,該塊被調用來幫助解決衝突。

基於這種理解,僅僅將散列傳遞給自身會導致它循環遍歷每個鍵值,因爲這就是update總是如何工作的。調用.each將是多餘的。

要更清楚地瞭解這一點,請查看#update方法的源代碼,並注意在任一邏輯分支中內部調用rb_hash_foreach

+0

因此,在發生衝突(重複鍵)的情況下,塊是原始哈希更新的規則?所以你可以說像{| key,value} value + = 1}之類的東西?您能否創建一個碰撞規則,以便您使用原始哈希值和第二個哈希值的平均值更新原始哈希值?試圖瞭解這種方法的範圍。非常感謝您的回覆。 – HectorOfTroy407 2014-08-27 20:54:11

+0

如果您檢查文檔,您會看到塊arity實際上接受3個參數:碰撞鍵,原始值和新值。所以是的,考慮到第二和第三個參數的平均值會給你結果:'{| key,v1,v2 | (v1 + v2)/ 2}' – PinnyM 2014-08-28 13:06:19