Arrays 元组数组,当第一个元素相同时求和

Arrays 元组数组,当第一个元素相同时求和,arrays,ruby,Arrays,Ruby,我试图通过按第一个元素分组来对数组的元素求和 ex: [[1, 8], [3, 16], [1, 0], [1, 1], [1, 1]] 应该给 [ {1 => 10}, {3 => 16} ] 它是对第一个元素为1和3的原始数组中的值求和。最终结果中的数据结构并不重要,例如:数组数组、散列数组或仅散列就可以了 一些尝试: k = [[1, 8], [3, 16], [1, 0], [1, 1], [1, 1]] h = {} k.inject({}) { |(a,b)| h[

我试图通过按第一个元素分组来对数组的元素求和

ex:
[[1, 8], [3, 16], [1, 0], [1, 1], [1, 1]]
应该给

[ {1 => 10},  {3 => 16} ]
它是对第一个元素为1和3的原始数组中的值求和。最终结果中的数据结构并不重要,例如:数组数组、散列数组或仅散列就可以了

一些尝试:

k = [[1, 8], [3, 16], [1, 0], [1, 1], [1, 1]]
h = {}
k.inject({}) { |(a,b)| h[a] += b}
#=>    undefined method `+' for nil:NilClass
给予

还有
inject
版本,尽管它不那么简洁:

data.inject({}) { |res, (k, v)| res[k] ||= 0; res[k] += v; res }

您已经非常接近了,需要对代码进行一些更改:

k.inject({}) do |hash, (a, b)|
  if hash[a].nil?
    hash[a] = b
  else
    hash[a] += b
  end

  hash
end
首先,您不需要
h
变量
#inject
接受一个参数,通常称为累加器,您可以为每个数组元素更改它,然后将其作为返回。因为您已经传递了一个空哈希来注入,所以不需要变量

接下来,您必须处理散列上还不存在键的情况,因此如果散列[a].nil?,则为
。在这种情况下,我们将
b
的值分配给散列,其中键是
a
。当散列中存在密钥时,我们可以安全地对值求和

另一件需要注意的事情是,您使用了错误的块参数。调用
#inject
时,首先接收累加器(在本例中为哈希),然后是迭代元素

文件

实际上,您在问题中使用了“groupby”,但在代码中从未对数组进行分组。在这里,我首先根据内部数组的第一个元素对它们进行分组,最后得到:

{ 1 => [[1, 8], [1, 0], [1, 1], [1, 1]], 3 => [[3, 16]] }

接下来,我只需要所有内部数组的最后一个元素,因为我已经知道第一个元素总是键,所以我使用
哈希#transform_值
将两个元素数组映射到它们的最后一个元素。最后,我
Enumerable#sum
这些数字。

逻辑不清楚。你是如何得到这个数组的?你的问题是什么?@codeObserver实际上1的和应该是10@user3309314你说得对。我纠正了它。谢谢此外,我意识到有一种更好的方式来表示问题的标题,表明我们正在对这个操作做些什么。在解析数据时听起来像是一个非常常见的操作。这不是预期的。作者说结束结果的结构无关紧要。这与结构无关。它是关于特定的值。8+0+1+1=10。我的问题有一个拼写错误guess@CarySwoveland
0
是不可变的,不需要长格式散列初始化:
arr.each_与_对象(hash.new(0)){(k,v),acc|acc[k]+=v}
k.inject({}) do |hash, (a, b)|
  if hash[a].nil?
    hash[a] = b
  else
    hash[a] += b
  end

  hash
end
k.group_by(&:first).transform_values {|v| v.map(&:last).sum }
{ 1 => [[1, 8], [1, 0], [1, 1], [1, 1]], 3 => [[3, 16]] }