Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.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 on rails 基于重复项求二维数组元素和的最简单方法?_Ruby On Rails_Arrays_Ruby - Fatal编程技术网

Ruby on rails 基于重复项求二维数组元素和的最简单方法?

Ruby on rails 基于重复项求二维数组元素和的最简单方法?,ruby-on-rails,arrays,ruby,Ruby On Rails,Arrays,Ruby,假设我有一个2D数组。可能是这样的: data = [['oct 1', 4], ['oct 2', 5], ['oct 3', 9], ['oct 1', 2]] 我想从中得到一个新的数组,它删除了重复的值(如10月1日),但对相应的值求和 因此,我最终会: data = (['oct 1', 6], ['oct 2', 5], ['oct 3', 9]) 我可以想出一些方法来做到这一点,但它们似乎效率很低,通常总有一些疯狂的ruby代码可以在几行内完成任何事情,有什么建议吗 尝试使用in

假设我有一个2D数组。可能是这样的:

data = [['oct 1', 4], ['oct 2', 5], ['oct 3', 9], ['oct 1', 2]]
我想从中得到一个新的数组,它删除了重复的值(如10月1日),但对相应的值求和

因此,我最终会:

data = (['oct 1', 6], ['oct 2', 5], ['oct 3', 9])

我可以想出一些方法来做到这一点,但它们似乎效率很低,通常总有一些疯狂的ruby代码可以在几行内完成任何事情,有什么建议吗

尝试使用
inject
方法执行以下操作:

data = [["oct 1", 4], ["oct 2", 5], ["oct 3", 9], ["oct 1", 2]]
data.inject({}) { |sum, (n, t)| sum[n] ||= 0; sum[n] += t; sum }.to_a
=> [["oct 1", 6], ["oct 2", 5], ["oct 3", 9]]

这里有几种方法可以做到这一点,我的偏好是第一种

使用计数哈希

代码

请参见,特别是对默认值的讨论

范例

解释

enum
的第一个值传递给块,并使用消歧和并行赋值计算块变量的值

现在,

enum
的其余三个值被传递到块并执行块计算

(date, val), h = enum.next
  #=> [["oct 2", 5], {"oct 1"=>4}]
h[date] += val 
  #=> 5 (the default value of `0` is again used)
h #=> {"oct 1"=>4, "oct 2"=>5} 

(date, val), h = enum.next
  #=> [["oct 3", 9], {"oct 1"=>4, "oct 2"=>5}] 
h[date] += val
  #=> 9 (the default value of `0` is again used)
h #=> {"oct 1"=>4, "oct 2"=>5, "oct 3"=>9} 

(date, val), h = enum.next
  #=> [["oct 1", 2], {"oct 1"=>4, "oct 2"=>5, "oct 3"=>9}] 
h[date] += val
  #=> 6 
h #=> {"oct 1"=>6, "oct 2"=>5, "oct 3"=>9} 
a = vals.map(&:last)
  #=> [4, 2] 
t = a.reduce(:+)
  #=> 6 
在上一次计算中,没有使用默认值,因为哈希
h
已经有一个键
“oct 1”

最后,

h.to_a
  #=> [["oct 1", 6], ["oct 2", 5], ["oct 3", 9]]
使用

代码

范例

解释

步骤如下:

h = data.group_by(&:first)
  #=> {"oct 1"=>[["oct 1", 4], ["oct 1", 2]],
  #    "oct 2"=>[["oct 2", 5]], "oct 3"=>[["oct 3", 9]]} 
h
的第一个键值对被传递到块:

date, vals = h.first
  #=> ["oct 1", [["oct 1", 4], ["oct 1", 2]]] 
date
  #=> "oct 1" 
vals
  #=> [["oct 1", 4], ["oct 1", 2]] 
并进行了分块计算

(date, val), h = enum.next
  #=> [["oct 2", 5], {"oct 1"=>4}]
h[date] += val 
  #=> 5 (the default value of `0` is again used)
h #=> {"oct 1"=>4, "oct 2"=>5} 

(date, val), h = enum.next
  #=> [["oct 3", 9], {"oct 1"=>4, "oct 2"=>5}] 
h[date] += val
  #=> 9 (the default value of `0` is again used)
h #=> {"oct 1"=>4, "oct 2"=>5, "oct 3"=>9} 

(date, val), h = enum.next
  #=> [["oct 1", 2], {"oct 1"=>4, "oct 2"=>5, "oct 3"=>9}] 
h[date] += val
  #=> 6 
h #=> {"oct 1"=>6, "oct 2"=>5, "oct 3"=>9} 
a = vals.map(&:last)
  #=> [4, 2] 
t = a.reduce(:+)
  #=> 6 
因此,
h
的第一个键值对被映射到

[date, t]
  #=> ["oct 1", 6]

其余的计算结果与此类似。

我们希望看到您尝试解决此问题。如果没有这些努力的证据,看起来你希望我们做你应该做的工作。请阅读“”和“”。谢谢,回答得很好。至于我的代码格式,我是这个网站的新手,所以我认为只要一个伪实现就可以了,我的错!关于如何将其推广到例如4D阵列的任何提示?这将取决于阵列的外观。例如,相同的密钥是否会出现在不同的“级别”?最好单独提出一个问题(举个例子)。
h.to_a
  #=> [["oct 1", 6], ["oct 2", 5], ["oct 3", 9]]
def combine(data) 
  data.group_by(&:first).map { |date, vals| [date, vals.map(&:last).reduce(:+)] }
end
combine data 
  #=> [["oct 1", 6], ["oct 2", 5], ["oct 3", 9]]
h = data.group_by(&:first)
  #=> {"oct 1"=>[["oct 1", 4], ["oct 1", 2]],
  #    "oct 2"=>[["oct 2", 5]], "oct 3"=>[["oct 3", 9]]} 
date, vals = h.first
  #=> ["oct 1", [["oct 1", 4], ["oct 1", 2]]] 
date
  #=> "oct 1" 
vals
  #=> [["oct 1", 4], ["oct 1", 2]] 
a = vals.map(&:last)
  #=> [4, 2] 
t = a.reduce(:+)
  #=> 6 
[date, t]
  #=> ["oct 1", 6]