2015-10-06 50 views
0

我寫了一個函數,使相同的字符(但不是相同的序列)的文字成hash[key],關鍵是這些字的字符排序的字符串例如,hash_list["arst"] => ["rats""tars""star"]關於在紅寶石散列(當一個數組散列到一些關鍵字)的問題

但是,在我的代碼中的第8行可能做錯了什麼,當我puts word_list,我得到一個{}

的名爲 「.txt」 文件中包含的單詞的多條線路,如:

alean 
allow 
away 
be 
behavior 
... 
... 

我的代碼:

01 def findAnagrams() 
02 word_list = Hash.new([]) # I set the default value here 
03 # word_list.default = Array.new 
04 File.open("/home/luchen/class/words.txt").each_line do |line| 
05  word = line.chomp.strip.downcase 
06  word_sort = word.chars.sort.join 
07  # puts word+"------"+word_sort 
08  word_list[word_sort].push(word) 
09  # puts word_list[word_sort] 
10 end 
11 puts word_list.to_s 
12 end 
13 
14 findAnagrams() 

回答

3

使用Hash#new與對象作爲參數,將返回相同的對象作爲默認值任意鍵不存在,也不會其值添加到哈希:

with_obj = Hash.new([]) 
with_obj[:test] 
# => [] 
with_obj[:test] << 1 
# => [1] 
with_obj 
# => {} # The :test key was not setted 
with_obj[:test2] 
# => [1] # The array object was changed when we did with_obj[:test] << 1 

但是你可以初始化一個哈希使用一個塊,然後用你想要的值設置新的鍵。使用塊這種方式將初始化一個新的數組的每個調用:

with_block = Hash.new { |hash, key| hash[key] = [] } 
with_block[:test] 
# => [] 
with_block[:test] << 1 
# => [1] 
with_block 
# => {:test=>[1]} # This time the key is setted 
with_block[:test2] 
# => [] # And any new key will use a new instance of array 
with_block 
# => {:test=>[1], :test2=>[]} 
+0

謝謝你的解釋! :) – lizlalala

1

您需要修改線路8成類似:

word_list[word_sort] ||= [] 
word_list.push(word) 

通過只讀訪問尚未存在的哈希元素,它不會被創建。

您必須寫信給它,即您需要致電[]=,而不僅僅是[]

+0

我初始化Hash.new的值([])和我認爲在紅寶石散列的新元素時一樣C++這樣做是將自動分配空間...順便說一句,我不明白|| = [] – lizlalala

+0

如果你查找一個未知的密鑰,則返回默認值。密鑰不會自動添加到散列。有關這些方法,請參閱Ruby文檔:http://ruby-doc.org/core-2.2.3/Hash.html#method-i-5B-5D –

+1

@lizlalala您可以使用塊代替像Hash .new {| h,k | h [k] = []}'。 – Doguita