13

私は配列を持っており、[1,2,4,5,4,7]各数値の頻度を見つけてハッシュに保存したいと考えています。私はこのコードを持っていますが、それは戻りますNoMethodError: undefined method '+' for nil:NilClass

def score( array )
  hash = {}
  array.each{|key| hash[key] += 1}
end

望ましい出力は

{1 => 1, 2 => 1, 4 => 2, 5 => 1, 7 => 1 }
4

8 に答える 8

21

以下のようにしてください:

def score( array )
  hash = Hash.new(0)
  array.each{|key| hash[key] += 1}
  hash
end
score([1,2,4,5,4,7]) # => {1=>1, 2=>1, 4=>2, 5=>1, 7=>1}

またはより Rubyish を使用Enumerable#each_with_object:

def score( array )
  array.each_with_object(Hash.new(0)){|key,hash| hash[key] += 1}
end
score([1,2,4,5,4,7]) # => {1=>1, 2=>1, 4=>2, 5=>1, 7=>1}

その理由はNoMethodError: undefined method '+' for nil:NilClass

hash = {}は空の has で、デフォルト値はnilです。nilは のインスタンスでありNilclass、 とNilClass呼ばれるインスタンス メソッドはありません#+。だからあなたは得NoMethodErrorました。

Hash::newドキュメントを見てください:

new → new_hash
new(obj) → new_hash

新しい空のハッシュを返します。その後、このハッシュがハッシュ エントリに対応しないキーによってアクセスされた場合、返される値は、ハッシュの作成に使用された new のスタイルによって異なります。最初の形式では、アクセスは nil を返します。obj が指定されている場合、この単一のオブジェクトがすべてのデフォルト値に使用されます。ブロックが指定されている場合、それはハッシュ オブジェクトとキーで呼び出され、デフォルト値を返す必要があります。必要に応じて、値をハッシュに格納するのはブロックの役割です。

于 2013-11-13T19:51:29.893 に答える