【问题标题】:How do I add a cumulative sum to an array for only one value?如何仅将一个值的累积和添加到数组中?
【发布时间】:2013-04-26 17:15:31
【问题描述】:

我有一个包含 x 和 y 值的数组:

[[some_date1, 1], [some_date2, 3], [some_date3, 5], [some_date4, 7]]

结果应该只对 y 值 (1, 3, 5, 7) 求和,因此结果如下:

[[some_date1, 1], [some_date2, 4], [some_date3, 9], [some_date4, 16]]

这在 Ruby 中怎么可能?

【问题讨论】:

  • 你试过什么?在您的问题中包含您试图找到解决方案的尝试很重要。这样我们就可以调整您的代码,而不是提供与您所做的事情无关的东西,迫使您将其硬塞到位,这可能会意外地引发错误。
  • 您应该避免使用具有固定位置的列表 - 最好使用散列代替,否则您的程序将像 NET::HTTP lib 一样难以遵循
  • 您的问题与时间序列无关。在问题和标题中放入无关信息是一个坏习惯。您可以使用:foo 等而不是some_date1 等(但现在修复可能为时已晚,因为一些答案基于此)。正如本网站的说明所说,尽可能使问题笼统。
  • 数据是用于绘制随时间变化的数据的图表,但它不像我预期的那样工作。在某些情况下,值会以某种方式下降,但从理论上讲,由于它是累积的,它应该只会上升。我认为问题在于数据与特定日期的多个条目组合的方式。因此,我认为我需要在积累之前每天总结。但是,这与我提出的问题无关,不会影响我的答案选择。

标签: ruby arrays multidimensional-array


【解决方案1】:
last = 0
arr.map do |a, b|
  last = last + b
  [a, last]
end

【讨论】:

    【解决方案2】:

    是的,这在 Ruby 中是可能的。您可以使用[map][1] 并执行以下操作:

    sum = 0
    array.map {|x,y| [x, (sum+=y)]}
    

    这就是它的工作原理。对于给定的输入:

    array = ["one", 1], ["two", 2]
    

    它将遍历数组中的每个元素,例如)第一个元素是["one", 1]

    然后它将获取该元素(它本身是一个数组)并将变量 x 分配给该数组中的第一个元素,例如)"one",并将 y 分配给第二个元素,例如)1

    最后,它会返回一个数组,结果如下:

    => ["one", 1], ["two", 3]
    

    【讨论】:

    • 是的,我忘了递增! :)
    【解决方案3】:

    你可以使用map:

    a = [[:some_date1, 1], [:some_date2, 3], [:some_date3, 5], [:some_date4, 7]]
    
    sum = 0
    a.map { |f, v| [f, (sum = sum + v)]}
    
    => [[:some_date1, 1], [:some_date2, 4], [:some_date3, 9], [:some_date4, 16]]
    

    由于sum 在第一次迭代中将是nil,因此有必要对其调用to_i

    【讨论】:

    • 我想你在迭代之前忘记像sum = 0一样初始化sum
    • 这个方法不需要初始化。
    • 我很确定你会这样做,否则每次迭代都是不同的sum
    • Ruby 将值nil 赋予一个未初始化的变量,to_i 方法将nil 转换为0
    • 我敢打赌,你在 irb 中定义了一个 sum,你正在测试它。试试这个新的:10.times { sum = sum.to_i + 1; puts sum }
    【解决方案4】:

    我会使用:

    ary = [['some_date1', 1], ['some_date2', 3], ['some_date3', 5], ['some_date4', 7]]
    ary.inject(0) { |m, a| 
      m += a[-1]
      a[-1] = m
    }
    

    运行后ary为:

    [["some_date1", 1], ["some_date2", 4], ["some_date3", 9], ["some_date4", 16]]
    

    我喜欢这个的原因是它不需要添加累加器变量。 inject 返回一个值,但它在没有赋值的情况下被丢弃。

    【讨论】:

    • 这对我来说似乎很可怕(虽然它很酷)。我一般不指望inject 修改调用者。
    • 这不是真的,它通过引用传递数组,这让我可以访问它们的值。与使用 map 相比的优势在于它不需要循环外的累加器值。
    • 这是注入的常见用法(修改调用数组)吗?我的理解是修改您正在迭代的对象是不好的做法。对不起,如果这有点离题。 (相关:groups.google.com/forum/?fromgroups=#!topic/ruby-core-google/…
    • 迭代和修改的方法有很多种。我唯一担心的是迭代何时会因修改而改变。 Ruby 的数组有map!,它的使用方式相同,可以就地修改,但这需要一个外部累加器,将其泄漏到外部变量空间中。
    • 嗯,这是一个! 函数,我希望对它进行一些修改。如果有注射!功能我对此没有问题。
    【解决方案5】:
    a = [['some_date1', 1], ['some_date2', 3], ['some_date3', 5], ['some_date4', 7]]
    a.each_cons(2){|a1, a2| a2[1] += a1[1]}
    

    【讨论】:

    • 对不起,我无法让这个工作。我什至试过require 'enumerator'
    猜你喜欢
    • 2023-03-10
    • 2014-02-20
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多