使用函数式编程按索引求和数组

时间:2014-12-31 18:09:12

标签: ruby arrays functional-programming

我有几个大小相同的数组(矩阵),我想用它们的索引(矩阵列)对它们求和。

例如,如果我有:

data = [[1, 2, 3, 4], [5, 6, 7, 8]]

我想得到结果:

column_totals = [6, 8, 10, 12]

我理解如何强制执行此操作,但我如何使用函数式编程? (最好使用内置的Enumerable方法。)我对我提出的任何功能解决方案都不满意。

我最终使用了Matrix类:

require 'matrix'

data = [[1, 2, 3, 4], [5, 6, 7, 8]]
matrix = Matrix[*data]
# Added sum method to Vector class.
matrix.column_vectors.map { |column| column.sum }

我对这个解决方案感到非常满意,但我很沮丧,我不能在不依赖Matrix类的情况下围绕一个好的功能解决方案。

具体来说,我被绊倒了改变它的步骤:

data = [[1, 2, 3, 4], [5, 6, 7, 8]]

进入这个:

columns = [[1, 5], [2, 6], [3, 7], [4, 8]]

2 个答案:

答案 0 :(得分:2)

有什么理由不使用Array#transpose

data.transpose
# => [[1, 5], [2, 6], [3, 7], [4, 8]]

或者,如果您只想使用Enumerable方法进行迭代,则可以执行

columns = data.inject(Array.new(data.first.length){[]}) { |matrix,row|
  row.each_with_index { |e,i| matrix[i] << e }
  matrix }
# => [[1, 5], [2, 6], [3, 7], [4, 8]]

columns = data.flatten.group_by.with_index { |e,i| i % data[0].size }.values
# => [[1, 5], [2, 6], [3, 7], [4, 8]]

总结:

columns.map { |row| row.inject :+ }
# => [6, 8, 10, 12]

第三,如果您不需要中间columns

data.inject { |s,r| s.zip(r).map { |p| p.inject :+ } }
# => [6, 8, 10, 12]

答案 1 :(得分:1)

您可以使用Array#transpose,如@Matt暗示的那样,然后对内部的数组求和:

data.transpose.map {|a| a.reduce(:+) }