Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 从数组和频率创建哈希_Ruby_Arrays_Hash - Fatal编程技术网

Ruby 从数组和频率创建哈希

Ruby 从数组和频率创建哈希,ruby,arrays,hash,Ruby,Arrays,Hash,我有一个数组[1,2,4,5,4,7],我想找到每个数字的频率并将其存储在散列中。我有这段代码,但它为nil:NilClass返回NoMethodError:undefined方法“+” def score( array ) hash = {} array.each{|key| hash[key] += 1} end 期望输出为 {1 => 1, 2 => 1, 4 => 2, 5 => 1, 7 => 1 } 按以下步骤进行: def score( a

我有一个数组
[1,2,4,5,4,7]
,我想找到每个数字的频率并将其存储在散列中。我有这段代码,但它为nil:NilClass返回
NoMethodError:undefined方法“+”

def score( array )
  hash = {}
  array.each{|key| hash[key] += 1}
end
期望输出为

{1 => 1, 2 => 1, 4 => 2, 5 => 1, 7 => 1 }
按以下步骤进行:

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}
或更多的红色使用:

nil:NilClass的
NoMethodError:undefined方法“+”的原因是什么

hash={}
是一个空has,默认值为
nil
nil
Nilclass
的一个实例,而
Nilclass
没有任何名为
+
的实例方法。所以你得到了
NoMethodError

查看文档:

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

爱我一些:

results=array.inject(Hash.new(0)){Hash,arr_元素}Hash[arr_元素]+=1;Hash}

1.9.3p448 :082 > array = [1,2,4,5,4,7]
 => [1, 2, 4, 5, 4, 7] 
1.9.3p448 :083 > results = array.inject(Hash.new(0)) {|hash, arr_element| hash[arr_element] += 1; hash }
 => {1=>1, 2=>1, 4=>2, 5=>1, 7=>1} 

只用注射。这种类型的应用程序正是它的用途。 比如:

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

下面是一个使用哈希数组初始值设定项的简短选项

Hash[arr.uniq.map {|v| [v, arr.count(v)] }]

这里的要点是当它第一次在数组中看到
1
时,
hash[1]
不存在(
nil


您需要以某种方式对其进行初始化,
hash=hash.new(0)
是最简单的方法
0
是本例中所需的初始值。

或使用group by方法:

arr = [1,2,4,5,4,7]

Hash[arr.group_by{|x|x}.map{|num,arr| [num, arr.size] }]
在Ruby 2.4+中:

def score(array)
  array.group_by(&:itself).transform_values!(&:size)
end

Ruby 2.7以后的版本将有
Enumerable#tally
方法来解决这个问题

从后备箱:

清点收藏。返回一个散列,其中键是元素,值是集合中与键对应的元素数


这将(IMO)更干净,因为
each_with_object
a.each_with_object(Hash.new(0)){e,h|h[e]+=1}
对每个人自己,@muistooshort:)我倾向于使用
inject
进行“反馈迭代”情况,而
对每个_with_object
进行“迭代和收集”情况。我厌倦了
;hash
stuff.mr,有人建议使用inject(aka reduce),这很好,但您所要做的就是将
hash={}
更改为
hash=hash.new(0)
。这告诉Ruby,如果它在必须有值的上下文中遇到
hash[key]
(例如
hash[key]+=1
v=hash[key]
),并且哈希不包含键
key
,那么在采取进一步的操作(例如
hash[key]+=1
)之前,它需要将
key=>0
添加到哈希中。另一方面,
if hash[key]==7
将计算为
if nil==7
如果
key
不在哈希中<代码>键=>0
将不会添加到哈希中。@CarySwoveland尼斯教学。。。!!我喜欢+1.@tokland,问题可能是一样的,但不是问题。在这里,mr.想知道他为什么会犯一个特别的错误,在我看来,这个错误很轻。很公平,那么让我们假设它是相关的:)
def score(array)
  array.group_by(&:itself).transform_values!(&:size)
end
["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}