我有几个大小相同的数组(矩阵),我想用它们的索引(矩阵列)对它们求和。
例如,如果我有:
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]]
答案 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(:+) }