2012-03-03 4 views
0

anagramsirbに呼び出すと、空のハッシュコンテナが期待通りに取得されます。しかし、print "No Key\n"行をコメントアウトすると、返されたハッシュコンテナは空になります。実際、リスト内のすべての要素について、elsifブランチのコードが実行されているようです。どちらか私はナッツつもりですか、ここで厄介なバグがあります:私はルビーIRBの次のバージョンがインストールされているブロック内のprintステートメントをarray.eachに使用した場合にのみRubyのバグが表示される

def anagrams(list = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream']) 
     aHash = Hash.new() 
     list.each { |el| 
      aKey = el.downcase.chars.sort.to_a.hash 
      if aHash.key?(aKey) 
       # print "Has Key\n" 
       aHash[aKey] << el 
      elsif 
       # print "No Key\n" 
       aHash[aKey] = [el] 
      end 
     } 

     return aHash 
end 

ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux] 
irb 0.9.6(09/06/30) 
+0

ちょうどノート:それは代わりに、 '{'/'の' do'/'end'を使用するRubyで慣例です} 'ブロックが複数の行にまたがるとき。 –

+0

また、私はこれを複製することはできません。 –

答えて

6

あなたの問題は、あなたがしているということですがelseを意味するelsifを使用します。この:

elsif 
    print "No Key\n" 
    aHash[aKey] = [el] 

は誤解を招くようなフォーマット、それは実際にはもっとこのように解釈される:

elsif(print "No Key\n") 
    aHash[aKey] = [el] 

が、printリターンをnilはそうロジックはこのようなものです:

elsif(nil) 
    aHash[aKey] = [el] 

nilが偽ブール値のコンテキストではaHash[aKey] = [el]は発生しません。あなたがprintを削除した場合、あなたはこれで終わる:

elsif(aHash[aKey] = [el]) 

と割り当てが発生します。 (配列があるので)ブール値のコンテキストでも代入は真ですが、この場合真理は無関係です。

if aHash.key?(aKey) 
    aHash[aKey] << el 
else 
    aHash[aKey] = [el] 
end 

さらに良いことには、そのデフォルト値として(ブロック経由)Arrayでハッシュを使用することです:

現在地elseを使用したい

aHash = Hash.new { |h, k| h[k] = [ ] } 

と、あなたドン

list.each do |el| 
    aKey = el.downcase.chars.sort.to_a.hash 
    aHash[aKey] << el 
end 

とすることができます:「Tはあなただけでこれを行うことができ、全くifを必要としますRubyハッシュで何かをキーとして使用しても、.to_a.hashにする必要がない場合でも、単に配列そのものをキーとして使うことができます。あなたも必要としないので、さらに、sortはあなたの配列を与えるto_a

list.each { |el| aHash[el.downcase.chars.sort] << el } 

誰かが、おそらく私はそれをやる、あなたの方法の終わりにreturn文句を言うだろう:あなたは必要ありません。あなたの方法の終わりにreturn、ちょうどaHashを言うと、それはメソッドの戻り値になります。

def anagrams(list = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream']) 
    aHash = Hash.new { |h, k| h[k] = [ ] } 
    list.each { |el| aHash[el.downcase.chars.sort] << el } 
    aHash 
end 

ます。また、さらに、それを圧縮するeach_with_objectを使用することができます。

def anagrams(list = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream']) 
    list.each_with_object(Hash.new { |h, k| h[k] = [ ] }) do |el, h| 
     h[el.downcase.chars.sort] << el 
    end 
end 

が、私はおそらく、ノイズを削減するために、このようにそれを行うだろう:

def anagrams(list = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream']) 
    h = Hash.new { |h, k| h[k] = [ ] } 
    list.each_with_object(h) { |el, h| h[el.downcase.chars.sort] << el } 
end 
関連する問題