2017-07-03 71 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}]