【问题标题】:Subtract one array of arrays from another ruby从另一个红宝石中减去一个数组数组
【发布时间】:2017-01-28 14:58:33
【问题描述】:

我有一系列月份和金额,像这样......

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 }

但似乎无法正确处理。我将不胜感激。

【问题讨论】:

  • @jordan,你说得对,对不起。这是漫长的一天
  • 你的意思是从a 中减去数组b 中的数量以与c 保持一致。
  • 两个数组中的月份是否总是具有相同的索引?
  • @stefan,是的,他们这样做了
  • 您仍然需要在“我需要从数组b 中的金额中减去数组a 中的金额”中反转ab 以与c 保持一致。

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


【解决方案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]

其余的计算类似。

【讨论】:

    【解决方案2】:

    这里还有另一种方法:

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

    【讨论】:

    • @CarySwoveland 感谢 Cary 的欢迎!一直忙于工作。我可能仍然不像 2015 年最后一个季度那样活跃,偶尔会幻影显形
    【解决方案3】:

    你可以使用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]]
    

    【讨论】:

      【解决方案4】:

      你离得不远了,但在你的尝试中你忘记了实际使用索引。

      你可能打算这样做:

      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 ] }
      

      【讨论】:

      • 这个 zip 方法给了我这个输出 [[[9, 2336.02], -2817.61], [[8, 7993.6], -7032.74], [[7, 5265.73], -5648.73], [[6, 7075.33], -9203.72], [[5, 9281.02], -8550.24], [[4, 9524.64], -6677.1], [[3, 300], -2205.84]]
      • 还有 each_with_index 产生的 [[[9, 2336.02], -2817.61], [[8, 7993.6], -7032.74], [[7, 5265.73], -5648.73], [[6, 7075.33], -9203.72], [[5, 9281.02], -8550.24], [[4, 9524.64], -6677.1], [[3, 300], -2205.84]] 不正确
      • 糟糕!是的,我在 a 上添加了一些东西。太好了!
      • #3:a.each_index.map {|i| [ a[i][0], a[i][1] - b[i][1] ] }.
      • 与只有一个(或两个)块变量相比,您在zip 方法中表达块变量的方式使其更易于阅读。
      猜你喜欢
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 2014-03-07
      相关资源
      最近更新 更多