2013-07-09 40 views
0

我正在写一个TFIDF程序 - 所有这些都应该没问题,但是我有一个小的(或很大的)问题,哈希按预期工作。为什么我的哈希函数不符合预期?

为了让这短暂的,手头上的代码是:

#Word matrix is an array that contains hashes (obviously) 
#i've done some stuff before this and these are working as expected 
puts word_matrix[3][:yahoo] # => 2 
puts word_matrix[100][:yahoo] # => 0 
puts $total_words_hash[:yahoo] #=> 0 

#Essentially, this block is taking a hash of all the words (values = 0) and trying 
#to run through them adding the only the values of the other hash to the temporary 
#and then setting the temp to the old hash position (so that there are 0 values 
#and the values occurring in that document.. yet, it assigns the same values to 
#ALL of the hashes of word_matrix[] 

#now we run this block and everything breaks down for some reason.. 
for i in 0...word_matrix.size 
    tmp_complete_words_hash = $total_words_hash #all values should be zero... 
    word_matrix[i].each do |key,val| #for each key in the hash we do this.. 
    tmp_complete_words_hash[key] = val 
    end 
    word_matrix[i] = tmp_complete_words_hash 
end 
puts word_matrix[3][:yahoo] # => 2 
puts word_matrix[100][:yahoo] # => 2 -- THIS SHOULD BE 0 Still... 

任何人都可以摆脱任何光线,为什么这是指派相同的值到阵列的所有散列值?这就好像tmp_complete_words_hash每次都没有被重置。

+0

就像一个参考:像'$ total_words_hash'这样的全局变量通常是错误的东西,在正确编写的代码中很少需要。在'... word_matrix.size'中为'i'使用'for'也不是惯用的Ruby。学习使用'each'和'map'来代替你的数组。 –

回答

2

您需要克隆散列。

tmp_complete_words_hash = $total_words_hash.clone 

否则,两个变量指向相同的散列,并且您不断修改该散列。

事实上,Ruby中的大多数对象都是这样的。只有少数(如数字,字符串)不是。

试试这个在IRB:

class MyClass 
    attr_accessor :value 
end 

x = MyClass.new 
y = x 
x.value = "OK" 
puts y.value 
+0

谢谢吉姆!完美的感觉! – user2243357

0

这是为什么分配相同的值到阵列的所有散列值?

只有一个散列。您在阵列中分配相同的散列(一个由$total_words_hash指出)的每个元素:

tmp_complete_words_hash = $total_words_hash 

在这里,你让tmp_complete_words_hash指向同一个对象$total_words_hash

word_matrix[i] = tmp_complete_words_hash 

在这里你将该散列分配给数组的每个元素。

0

当您将散列变量分配给另一个散列变量时。它会引用相同的内存位置,如果您更改一个散列,则相同的内容将反映到另一个散列。

total_words_hash = {} 
tmp_complete_words_hash = total_words_hash 
1.9.3 (main):0 > total_words_hash.object_id 
=> 85149660 
1.9.3 (main):0 > tmp_complete_words_hash.object_id 
=> 85149660 
total_words_hash[:test] = 0 
1.9.3 (main):0 > tmp_complete_words_hash 
=> { 
    :test => 0 
} 
1.9.3 (main):0 > tmp_complete_words_hash[:test_reverse] = 1 
=> 1 
1.9.3 (main):0 > tmp_complete_words_hash 
=> { 
     :test => 0, 
     :test_reverse => 1 
} 

因此,您可以使用散列方法dup为此目的创建一个重复散列。

1.9.3 (main):0 > tmp_complete_words_hash = total_words_hash.dup 
1.9.3 (main):0 > total_words_hash.object_id 
=> 85149660 
1.9.3 (main):0 > tmp_complete_words_hash.object_id 
=> 97244920 

在你的情况只是使用。

tmp_complete_words_hash = $total_words_hash.dup 
相关问题