2014-10-29 54 views
2

下面我們給出一個名爲win_lose的數組。我們應該創建一個哈希,看起來像下面的哈希。我最初的意圖是使用.count來做某些事情,但在嘗試回答之後,.each_with_object工作得最好。.each_with_object ruby​​解釋?

有人可以爲我分解什麼.each_with_object方法正在做的和答案本身?我得到了答案,並從閱讀文檔中找出它,但仍然需要解釋方法本身...

謝謝!

win_lose = ["win", "lose", "win", "lose", "win", "win"] 

創建基於win_lose陣列上的哈希,看起來像這樣:

這是我最初嘗試沒有成功:

win_loss_count = Hash[win_lose.map.with_index { |outcome, times| outcome = times.count }] 

答:

win_loss_count = win_lose.each_with_object(Hash.new(0)) { |word,counts| counts[word] += 1 } 

回答

5

each_with_object的字面意思就是它所說的。這就像each,但每次都有一個額外的對象。

因此,對於這個:

win_lose.each_with_object(Hash.new(0)) { |word,counts| counts[word] += 1 } 

你打電話each,與對象通過Hash.new(0)傳入爲好,每次創建。 word是你在正常的each中得到的單詞,而counts是被稱爲「with_object」的對象(所以,哈希)。

重要的是這個快捷方式是Hash.new(0)。這意味着創建一個新的空散列,其中0表示所有以前不存在的鍵的值,即使它以前不存在,也可以執行counts[word] += 1

最後,each_with_object返回「對象」,所以返回counts,對每個單詞都進行了修改。

+2

謝謝尼克這個徹底的解釋。我現在明白它好多了! – user3604867 2014-10-29 17:03:56

2

尼克有它完全正確的,事實上有其他方法可以傳遞對象到一個塊來幫助你,但是你的結構需要輸出。在紅寶石中最常見的一種方法是Enumerable#inject方法。你同樣的答案可以寫成像

win_lose.inject(Hash.new(0)) { |hash, val| hash[val] += 1; hash } 

執行相同的操作:

[14] pry(main)> win_lose 
=> ["win", "lose", "win", "lose", "win", "win"] 
[15] pry(main)> win_lose.inject(Hash.new(0)) { |hash, val| hash[val] += 1; hash } 
=> {"win"=>4, "lose"=>2} 

我們正在做同樣的事情,我們在哈希誰的默認值要發送到零到塊,我們正在每次迭代構建新的散列。

+1

謝謝安東尼!使用.inject是非常有用的。感謝您將我的注意力引入並解釋! – user3604867 2014-10-29 17:03:35

+0

安東尼 - 問題 - 在這個部分:win_lose.inject(Hash.new(0)){| type,num |鍵入[num] + = 1;類型} ...如果我沒有寫分號和類型(或像上面那樣的散列),我得到這個錯誤:「沒有將字符串隱式轉換爲整數」。這是爲什麼? – user3604867 2014-10-29 17:40:28

+0

當然,您必須將散列返回到塊中,這就是分號正在做的事情。同時,我們實例化Hash.new(0),它修復了您引用的字符串 - >整數問題。 – Anthony 2014-10-29 17:48:23