2017-07-03 72 views
0

迭代時,我每次都將一些數據保存爲哈希。在同一個循環中,我將散列推送到一個數組中。Ruby - 將哈希推向陣列

下面的代碼不起作用,最後一個哈希對象會覆蓋數組中的所有其他哈希對象。

playlists = [] 
aPlaylist = {} 

while (count < 3) 
    #some code... produces the hash "aPlaylist" 
    playlist << aPlaylist 
end 

下面的代碼確實有效。爲什麼,還有什麼區別?

playlists = [] 

while (count < 3) 
    aPlaylist = {} 
    #some code... produces the hash "aPlaylist" 
    playlist << aPlaylist 
end 

這裏是正確與錯誤輸出(轉換成CSV): http://imgur.com/a/rjmBA

+0

_「最後散列對象覆蓋數組中的所有其他數據「_ - 你能顯示錯誤的結果嗎? – Stefan

+0

這完全取決於您遺漏的「某些代碼」。 –

+0

我用圖像更新了問題。 @JörgWMittag我不這麼認爲,其他答案解釋了原因。 – Emre

回答

2

因爲在第一種情況下,對象與0,1和第二個索引相同。

playlist = [] 
aPlaylist = {} 
count = 0 

while (count < 3) 
    #some code... produces the hash "aPlaylist" 
    playlist << aPlaylist 
    puts aPlaylist.object_id 
    count += 1 
end 
#=> 2048 
#=> 2048 
#=> 2048 

而在第二種情況下它的變化:

playlist = [] 

count = 0 

while (count < 3) 
    aPlaylist = {} 
    #some code... produces the hash "aPlaylist" 
    playlist << aPlaylist 
    puts aPlaylist.object_id 
    count += 1 
end 
#=> 2048 
#=> 2038 
#=> 2028 

這就是爲什麼從當您更改哈希第二種情況下,它不會反映在陣列中的所有地方。

閱讀this stackoverflow answer瞭解更多詳情。

+0

哦,我現在看到。 因此,基本上,當我在每次迭代中更新一個Playlist時,它都是對數組進行傳遞的引用,並且它們也發生了變化。 這對我來說有點不直觀,來自C++背景。 – Emre

+0

@emre要小心,你最終不會在Ruby中編寫C++。 –

+0

@david照顧詳細說明?我是一個單身漢,做了他的第一次實習,所以沒有經驗。 – Emre

0

aPlaylist = {}創建一個散列,aPlaylist變量保存一個指向散列對象的指針。

在你的第一個例子中,你只編輯這一個散列對象。

aPlaylist = {} 
count = 0 
while (count < 3) 
    puts aPlaylist.object_id 
    count += 1 
end 
#=> 70179174789100 
#=> 70179174789100 
#=> 70179174789100 

在你的第二個例子中,你在每次迭代中創建一個新的散列對象。這就是這種代碼的工作方式。

count = 0 
while (count < 3) 
    aPlaylist = {} 
    puts aPlaylist.object_id 
    count += 1 
end 
#=> 70179182889040 
#=> 70179182888980 
#=> 70179182888920 

看看打印的對象-id。

0

我覺得一個地道的Ruby的方式會是這樣的......

playlist = 0.upto(2).map{|count| something_that_returns_a_hash } 

......或者......

playlist = (0..2).map{|count| something_that_returns_a_hash } 

因此:

0.upto(2).map{|count| {count => count} } 

[{0=>0}, {1=>1}, {2=>2}]