为什么我的Hash不能按预期运行?

时间:2013-07-09 01:25:13

标签: ruby hash

我正在编写一个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每次都没有被重置。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

在这里,您将该哈希值分配给数组的每个元素。

答案 2 :(得分: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