我假設,對於string
中的每個單詞,您希望確定dictionary
中該單詞的實例數。如果是這樣,第一步是創建一個計數散列。
dict_hash = dictionary.each_with_object(Hash.new(0)) { |word,h| h[word] += 1 }
#=> {"to"=>3, "do"=>3}
(我將在稍後解釋此代碼。)
現在拆分上空白string
並創建一個哈希的鍵是字符串的話,其值的次數是的word
值出現在dictionary
。
string.split.each_with_object({}) { |word,h| h[word] = dict_hash.fetch(word, 0) }
#=> {"just"=>0, "do"=>3, "it"=>0, "to"=>3}
這當然假設string
中的每個單詞都是唯一的。如果不是,根據所需的行爲,一種可能性是使用另一個計數散列。
string = "to just do it to"
string.split.each_with_object(Hash.new(0)) { |word,h|
h[word] += dict_hash.fetch(word, 0) }
#=> {"to"=>6, "just"=>0, "do"=>3, "it"=>0}
現在讓我來解釋一下上面的一些構造。
我使用類方法Hash::new的形式創建了兩個散列,它們的參數等於期望的默認值,這裏是零。這也就意味着,如果
h = Hash.new(0)
和h
沒有一鍵等於價值word
,然後h[word]
將返回h
的默認值(和哈希h
不會改變)。在創建第一個散列之後,我寫了h[word] += 1
。 Ruby將其擴展到
h[word] = h[word] + 1
在她做任何進一步處理之前。傳遞給塊的string
中的第一個字是"to"
(它被分配給塊變量word
)。由於哈希h
是最初是空的(無鑰匙),h[word]
上述等式的右邊返回默認值零,給我們
h["to"] = h["to"] + 1
#=> = 0 + 1 => 1
後來,當word
再次等於"to"
默認值是沒有使用,因爲h
現在有一個密鑰"to"
。
h["to"] = h["to"] + 1
#=> = 1 + 1 => 2
我使用了很好的方法Enumerable#each_with_object。對於新手來說,這可能看起來很複雜。事實並非如此。行
dict_hash = dictionary.each_with_object(Hash.new(0)) { |word,h| h[word] += 1 }
有效是相同如下。
h = Hash.new(0)
dict_hash = dictionary.each { |word| h[word] += 1 }
h
換句話說,該方法允許一個編寫創建,構造並返回散列值,而不是三行做同樣的單行。
注意,我使用的方法Hash#fetch用於從散列檢索值:
dict_hash.fetch(word, 0)
fetch
的第二個參數(這裏0
)被返回,如果dict_hash
不具有相等的鍵的word
值。相反,在這種情況下,dict_hash[word]
返回nil
。
1「有效」的原因是當使用each_with_object
時,變量h
的作用域被限制在塊中,這通常是一種很好的編程習慣。如果您還沒有了解「範圍」,請不要擔心。
你有沒有考慮過使用包含多個單詞的測試字符串來嘗試它? – Hamms
我剛剛做到了。它計數....但它是在計算我的字符串。世界背後是什麼? –
當您舉一個例子時,您應該始終顯示所需的輸出。我真的不明白你想要做什麼。首先,由於您將第一個數組命名爲「dictionary」,因此我不希望它包含重複項。另外,返回值的格式應該是什麼?哈希,也許? –