从另一个ruby中减去一个数组数组

时间:2016-09-20 15:34:31

标签: arrays ruby ruby-on-rails-4 hash

我有几个月的数量,如此数量......

a = [[9, 2336.02], [8, 7993.6], [7, 5265.73], [6, 7075.33], [5, 9281.02], [4, 9524.64], [3, 300]]

然后我又有了另一个......

b = [[9, 2817.61], [8, 7033.74], [7, 5650.73], [6, 9206.72], [5, 8554.24], [4, 6682.1], [3, 2211.84]]

我需要在保持键的同时从数组b中的数量中减去数组a中的数量。所以我的输出应该看起来像

c = [[9,-481.59], [8, 959.86],[...]]

我试过

a.each_with_index.map { |month, amount| amount - b.each { |months,cost| cost }

但似乎无法做到正确。我将不胜感激任何帮助。

4 个答案:

答案 0 :(得分:4)

您可以使用zip

c = a.zip(b).map{|k| [k[0][0], (k[0][1] - k[1][1]).round(2)] }
#=> [[9, -481.59], [8, 959.86], [7, -385.0], [6, -2131.39], [5, 726.78], [4, 2842.54], [3, -1911.84]]

答案 1 :(得分:3)

你并不遥远,但在你的尝试中,你忘了实际使用索引。

你可能想做这样的事情:

a.each_with_index.map {|(month, amount), i| [ month, amount - b[i][1] ] }

我们可以使用Array#zip

使这更像“Rubyish”
a.zip(b).map {|(month, amount_a), (_, amount_b)| [ month, amount_a - amount_b ] }

答案 2 :(得分:1)

这是另一种方式。

[a,b].transpose.map(&:transpose).map { |(e,_),arr| [e, arr.reduce(:-)] }
  #=> [[9, -481.59000000000015], [8, 959.8600000000006], [7, -385.0],
  #    [6, -2131.3899999999994], [5, 726.7800000000007], [4, 2842.539999999999],
  #    [3, -1911.8400000000001]] 

步骤如下。

c = [a,b].transpose
  #=> [[[9, 2336.02], [9, 2817.61]], [[8, 7993.6], [8, 7033.74]],
  #    [[7, 5265.73], [7, 5650.73]], [[6, 7075.33], [6, 9206.72]],
  #    [[5, 9281.02], [5, 8554.24]], [[4, 9524.64], [4, 6682.1]],
  #    [[3, 300], [3, 2211.84]]] 
d = c.map(&:transpose)
  #=> [[[9, 9], [2336.02, 2817.61]], [[8, 8], [7993.6, 7033.74]],
  #    [[7, 7], [5265.73, 5650.73]], [[6, 6], [7075.33, 9206.72]],
  #    [[5, 5], [9281.02, 8554.24]], [[4, 4], [9524.64, 6682.1]],
  #    [[3, 3], [300, 2211.84]]] 
d.map { |(e,_),arr| [e, arr.reduce(:-)] }
  #=> [[9, -481.59000000000015], [8, 959.8600000000006], [7, -385.0],
  #    [6, -2131.3899999999994], [5, 726.7800000000007], [4, 2842.539999999999],
  #    [3, -1911.8400000000001]] 

让我们更仔细地研究最后的计算。

enum = d.map
  #=> #<Enumerator: [[[9, 9], [2336.02, 2817.61]], [[8, 8], [7993.6, 7033.74]],
  #                  [[7, 7], [5265.73, 5650.73]], [[6, 6], [7075.33, 9206.72]],
  #                  [[5, 5], [9281.02, 8554.24]], [[4, 4], [9524.64, 6682.1]],
  #                  [[3, 3], [300, 2211.84]]]:map> 

枚举器生成的第一个元素将传递给块并分配给块变量。

(e,_),arr = enum.next
  #=> [[9, 9], [2336.02, 2817.61]] 
e #=> 9
_ #=> 9
arr
  #=> [2336.02, 2817.61] 
arr.reduce(:-)
  #=> -481.59000000000015 

所以返回数组[9, -481.59000000000015]

其余的计算方法类似。

答案 3 :(得分:1)

以下是另一种方法:

(0...a.size).map { |i| [a[i].first, a[i].last - b[i].last] }