计算Ruby中多个值的运行总数

计算Ruby中多个值的运行总数,ruby,Ruby,我尝试对多个值求和,例如 [4444.33,0333.444,0] [3333.444,01123.445444] [321112.443.3,04444] 我正在考虑一个循环,但我不知道如何继续: values = [] (0..3).each do |value| # values << [4444.33, 0, 333.444, 0] on 1st iteration # values << [3333.444, 0, 1123.44, 5

我尝试对多个值求和,例如

  • [4444.33,0333.444,0]
  • [3333.444,01123.445444]
  • [321112.443.3,04444]
我正在考虑一个循环,但我不知道如何继续:

values = []

(0..3).each do |value|
  # values << [4444.33, 0, 333.444, 0]       on 1st iteration
  # values << [3333.444, 0, 1123.44, 5444]   on 2nd iteration
  # values << [321112.4, 443.3, 0, 4444]     on 3rd iteration

  # Here I need to add each array with the next one
end
值=[]
(0..3)。每个do值|
#值更新1:
这不会改变任何事情。 您仍然可以应用这些代码

(0..3).each do |value|
  # First loop 
    values << [4444.33,0,333.444,0]
  # Second loop 
    values << [3333.444,0,1123.44,5444]
  # Third loop
    values << [321112.4,443.3,0,4444] 
  # Here I need to add each array with the next one
    values.transpose.map {|x| x.reduce(0, :+)}
end

由于初始数组中的子数组长度恒定,因此可以使用每个结果数组,然后求和

轨道

values.transpose.map(&:sum)
或者,如果您使用的是2.4以上的ruby版本,请使用纯ruby(多亏了Sebastian Palma)

第一个答复:

values.transpose.map(&:sum)

更新

values.map.with_索引{v,i | i>1?[*v,values.dig(0,0),values.dig(1,0)]:v}

我想添加第一个数组的第一个元素和第二个数组的第一个元素,就像所有四个集合的第一个元素一样[…],就像一个连续的总数

要获取运行总计,可以首先创建一个大小正确的空“总计”数组:

totals = [0, 0, 0, 0]
添加一行意味着将每一行的值添加到相应的总计中

这可以通过多种方式完成,例如手动:

row = [4444.33, 0, 333.444, 0]

totals[0] += row[0]
totals[1] += row[1]
totals[2] += row[2]
totals[3] += row[3]

p totals #=> [4444.33, 0, 333.444, 0]
或通过行上的:

row = [3333.444, 0, 1123.44, 5444]

row.each_with_index { |v, i| totals[i] += v }

p totals #=> [7777.773999999999, 0, 1456.884, 5444]
或者通过(请注意
)和
总计
数组:

row = [321112.4, 443.3, 0, 4444]

totals.map!.with_index { |t, i| t + row[i] }

p totals #=> [328890.174, 443.3, 1456.884, 9888]

您可以将一的行向量与转换为矩阵的数组相乘,然后将结果转换回总和数组

values = [
  [  4444.33,    0,    333.444,    0],
  [  3333.444,   0,   1123.44,  5444],
  [321112.4,   443.3,    0,     4444]
]

见和

注:

我的两美分使用,只要它们已经存储在变量中:

a = [4444.33, 0, 333.444, 0]
b = [3333.444, 0, 1123.44, 5444]
c = [321112.4, 443.3, 0, 4444]

a.zip(b, c).map &:sum
#=> [324890.174, 443.3, 1456.884, 9888]
否则:

values = [a, b, c]
values.inject([0,0,0,0]) { |acc, e| acc.zip(e).map &:sum }

但是转置然后映射到求和是一种更干净的方法。

您的示例具有嵌套数组。你想展平它,然后分别添加还是全部添加?我不想展平它,因为正如我在上面的示例中所说的,我想添加第一个数组的第一个元素和第二个数组的第一个元素,就像这四个集合一样。所以我想单独做。它是我自己创建的,因为你会有一个想法,对不起。我不明白你发布的代码的目的:你用12个元素填充
,它们也是4个元素的数组。那很好。你可以得到一个12x4矩阵。那么你想用它做什么呢?阿马尔,当你被要求澄清你的问题时,你应该编辑你的问题,而不是用评论来回答。问题应该独立存在,部分原因是读者不应该通过阅读所有评论来理解问题。当你编辑问题时,就像编辑论文一样。例如,不要写“EDIT:”。我想您应该删除“for Rails”。使用
inject
时,如果要求和的数组为空,通常最好添加一个初始值零。您不需要“第一个答案”和“更新”。只需默默编辑,给出一种或两种方法。在我看来,#2冲淡了一个干净的回答。
require 'matrix'

(Matrix.row_vector([1]*values.size) * Matrix[*values]).to_a.flatten
 => [328890.174, 443.3, 1456.884, 9888] 
a = Matrix.row_vector([1]*values.size)
  #=> Matrix[[1, 1, 1]] 
b = Matrix[*values]
  #=> Matrix[[4444.33, 0, 333.444, 0],
  #          [3333.444, 0, 1123.44, 5444],
  #          [321112.4, 443.3, 0, 4444]] 
a*b
  #=> Matrix[[328890.174, 443.3, 1456.884, 9888]] 
a = [4444.33, 0, 333.444, 0]
b = [3333.444, 0, 1123.44, 5444]
c = [321112.4, 443.3, 0, 4444]

a.zip(b, c).map &:sum
#=> [324890.174, 443.3, 1456.884, 9888]
values = [a, b, c]
values.inject([0,0,0,0]) { |acc, e| acc.zip(e).map &:sum }