2012-07-21 115 views
10

散列我嘗試以下紅寶石代碼,我認爲將字長的散列返回到與那些長度的話。相反,它是空的。紅寶石添加具有數組值

map = Hash.new(Array.new)  
strings = ["abc","def","four","five"] 
strings.each do |word| 
    map[word.length] << word 
end 

但是,如果我將它修改爲

map = Hash.new 
strings = ["abc","def","four","five"] 
strings.each do |word| 
    map[word.length] ||= [] 
    map[word.length] << word 
end 

它的工作。

不第一個版本剛創建哈希值,其默認值是空數組?在這種情況下,我不明白爲什麼這兩個區塊會給出不同的值。

+0

這是奇怪的。對於第一個例子,如果你執行'map = Hash.new {| h,k | h [k] = []}' – 2012-07-21 03:56:33

回答

21

的問題是,你沒有,你只是使用<<操作員修改默認值的現有內容實際上任何分配到哈希鍵。由於您不會將任何內容分配給散列鍵,因此不會添加它。事實上,你會發現默認值是一個修改:

h = Hash.new [] 
p h[0]   # [] 
h[0] << "Hello" 
p h    # {} 
p h[0]   # ["Hello"] 
p h[1]   # ["Hello"] 

這是因爲相同Array對象保持爲默認值。您可以通過使用+運營商解決它,儘管它可能是低效率:

map = Hash.new [] 
strings = ["abc", "def", "four", "five"] 

strings.each do |word| 
    map[word.length] += [word] 
end 

而現在它按預期工作。

+0

幫了我很多,謝謝!直到我後'+ ='是一個數組,比如'[文字]' – Subtletree 2013-12-27 11:50:06

2

我覺得第一個版本的真正含義是默認值只有一個數組。第二個例子明確地創建一個新的數組,如果還不存在的話。

這看起來像一個良好的閱讀,以進一步clarify

+0

啊,我明白了。這就說得通了。 – 2012-07-21 03:59:35

11

在任何情況下,你應該使用Enumerable#group_by

["abc", "def", "four", "five"].group_by(&:length) 
#=> {3=>["abc", "def"], 4=>["four", "five"]} 
+0

由於改變了'word'這並沒有爲我工作,但是。我仍然在學習Ruby,所以學習這些習語很有幫助。 – 2012-07-21 13:49:31

+0

輝煌,謝謝! – Johnsyweb 2013-07-15 23:14:06