2017-06-15 67 views
1

初始化紅寶石哈希,如:紅寶石哈希初始化與each_with_object行爲古怪

keys = [0, 1, 2] 
hash = Hash[keys.each_with_object([]).to_a] 

試圖插入值到鍵時行爲古怪。

hash[0].push('a') 
# will result into following hash: 
=> {0=>["a"], 1=>["a"], 2=>["a"]} 

我只是想插入到一個鍵,但它是更新所有鍵的值。

+0

@SergioTulentsev你能告訴我發生了什麼事嗎?我只是想用具有值的鍵作爲數組初始化散列。它創建一個散列,但後來插入,它的行爲怪異,我沒有得到爲什麼的一部分。 – jaiswal

回答

3

是的,這each_with_object本身超怪異。這不是應該如何使用它。並且問題出現恰恰是,因爲您誤用了它。

keys.each_with_object([]).to_a 
# => [[0, []], [1, []], [2, []]] 

你看,即使它看起來這些陣列是獨立的,它實際上是在這三種情況下在同一個陣列。這就是爲什麼如果你把一個元素合併成一個元素,它就會出現在其他元素中。

這裏有一個更好的辦法:

h = keys.each_with_object({}) {|key, h| h[key] = []} 
# => {0=>[], 1=>[], 2=>[]} 

或者說

h = keys.zip(Array.new(keys.size) { [] }).to_h 

或者其他的一些方式。

如果你不關心散列有這個確切的密鑰集合,並且只想要所有的鍵都有空數組作爲默認值,這也是可能的。

h = Hash.new { |hash, key| hash[key] = [] } 
+2

或者說'keys.map {| k | [k,[]]} .to_h' ... –

+0

@ Md.Fhanhan:是的,這個也不錯。 –

+1

'3'應該是'keys.size' – Stefan

0

您的所有密鑰參考相同的數組。

簡化版本,解釋了這個問題:

a = [] 
b = a 
a.push('something') 
puts a #=> ['something'] 
puts b #=> ['something'] 

即使你有兩個變量(ab)只有一個陣列對象。因此,對變量的參考由變量a的任何改變也將改變數組參考變量b。因爲它是同一個對象。

的長版的你正在努力實現將是什麼:

keys = [1, 2, 3] 
hash = {} 
keys.each do |key| 
    hash[key] = [] 
end 

和較短的版本:

[1, 2 ,3].each_with_object({}) do |key, accu| 
    accu[key] = [] 
end 
-1

爲什麼你把它們放在一個數組中,之後你把它們放進一個散列?如果我理解正確你的問題,你可能會想這樣做:

hash = {'1'=>"",'2'=>"",'3'=>""} 
hash['1'] = 'a' 
hash['2'] = 'b' 
hash['3'] = 'Hello' 

您可以在此之後將其轉換爲整數或任何你想要的,如果該對象的類不能滿足您的要求! 希望它有幫助!

+0

你爲什麼認爲OP想要這樣做? –