从数组和频率创建哈希

ste*_*iel 10 ruby arrays hash

我有一个数组[1,2,4,5,4,7],我想找到每个数字的频率并将其存储在哈希中.我有这个代码,但它返回NoMethodError: undefined method '+' for nil:NilClass

def score( array )
  hash = {}
  array.each{|key| hash[key] += 1}
end
Run Code Online (Sandbox Code Playgroud)

期望的输出是

{1 => 1, 2 => 1, 4 => 2, 5 => 1, 7 => 1 }
Run Code Online (Sandbox Code Playgroud)

Aru*_*hit 17

请执行以下操作:

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}
Run Code Online (Sandbox Code Playgroud)

或者更多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}
Run Code Online (Sandbox Code Playgroud)

原因是NoMethodError: undefined method '+' for nil:NilClass什么?

hash = {}是一个空的has,默认值为nil.nil是一个实例Nilclass,并且NilClass没有调用任何实例方法#+.所以你得到了NoMethodError.

看看Hash::new文档:

new ? new_hash
new(obj) ? new_hash
Run Code Online (Sandbox Code Playgroud)

返回一个新的空哈希.如果随后通过与散列条目不对应的键访问此散列,则返回的值取决于用于创建散列的新样式.在第一种形式中,访问返回nil.如果指定了obj,则此单个对象将用于所有默认值.如果指定了一个块,它将使用哈希对象和键调用,并应返回默认值.如果需要,块负责将值存储在哈希中.


mwp*_*mwp 13

在Ruby 2.4+中:

def score(array)
  array.group_by(&:itself).transform_values!(&:size)
end
Run Code Online (Sandbox Code Playgroud)


Jos*_*osh 10

只需使用注入.这种类型的应用程序正是它的意思.就像是:

a.inject(Hash.new(0)) {|hash,word| hash[word] += 1; hash }
Run Code Online (Sandbox Code Playgroud)


Paw*_*wan 9

Ruby 2.7 以后Enumerable#tally会有解决这个问题的方法。

从主干文档

统计集合。返回一个散列,其中键是元素,值是集合中与键对应的元素数。

["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
Run Code Online (Sandbox Code Playgroud)