如何对二维数组求和
How to sum 2-dimensional arrays
我有一个二维数组,其子数组大小相等,例如:
array = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88]
]
我想通过对每第 4 个子数组的相应元素求和来创建一个新数组,即上面示例中 "on top of each other" 的元素:
new_array = [
[10 + 36, 12 + 25, 15 + 74, 17 + 98],
[16 + 32, 32 + 19, 65 + 66, 47 + 88],
[45, 48, 41, 23]
]
这些只是示例,实际数组可以更大。
完整矩阵
您可以再次使用 each_slice
, transpose
, map
and transpose
来导航您的矩阵。
该代码首先使用 join('+')
来显示正在计算的内容:
array= [[10,12,15,17],[16,32,65,47],[45,48,41,23],[36,25,74,98],[32,19,66,88],[1,2,3,4]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.join('+')}}
# => [["10+36", "12+25", "15+74", "17+98"], ["16+32", "32+19", "65+66", "47+88"], ["45+1", "48+2", "41+3", "23+4"]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
# => [[46, 37, 89, 115], [48, 51, 131, 135], [46, 50, 44, 27]]
警告!
您需要仔细 select each_slice
参数以适合您的原始数组。 transpose
否则可能会引发异常:
array = [[10,12,15,17],[19,32,65,47],[45,48,41,23],[36,25,74,98],[10,12,15,17],[16,98,65,47],[69,48,65,23],[66,25,74,98]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
#=> IndexError: element size differs (2 should be 3)
array.each_slice(4).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
#=> [[20, 24, 30, 34], [35, 130, 130, 94], [114, 96, 106, 46], [102, 50, 148, 196]]
矩阵不完整
如果矩阵 size
不是 width
的倍数:
array = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88]
]
您可以添加全为 0 的子数组以获得:
matrix = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88], [ 0, 0, 0, 0]
]
Array#fill 完成任务:
def maxtrix_column_sums(array, width)
size = array.size
size2 = array.first.size
missing = (-size) % width
matrix = array.dup.fill(Array.new(size2, 0), size...size + missing)
matrix.each_slice(width).to_a.transpose.map { |r| r.transpose.map { |x| x.join('+') } }
end
p maxtrix_column_sums(array, 3)
#=> [["10+36", "12+25", "15+74", "17+98"], ["16+32", "32+19", "65+66", "47+88"], ["45+0", "48+0", "41+0", "23+0"]]
这是 的变体,使用 zip
而不是 transpose
来说明 "odd" 个子数组:
first, *rest = array.each_slice(3).to_a
first.zip(*rest).map { |r| r.compact.transpose.map { |x| x.inject(:+) } }
#=> [[46, 37, 89, 115], [48, 51, 131, 135], [45, 48, 41, 23]]
工作原理:
each_slice
将数组分成 3 组:
array.each_slice(3).to_a
#=> [
# [[10, 12, 15, 17], [16, 32, 65, 47], [45, 48, 41, 23]],
# [[36, 25, 74, 98], [32, 19, 66, 88]]
# ]
first.zip(*rest)
将第一个切片 "column"-wise 与其余切片组合,在缺少切片时添加 nil
:
first.zip(*rest)
#=> [
# [[10, 12, 15, 17], [36, 25, 74, 98]],
# [[16, 32, 65, 47], [32, 19, 66, 88]],
# [[45, 48, 41, 23], nil]
# ]
map
/ compact
/ transpose
部分然后重组子数组,同时摆脱 nil
值:
first.zip(*rest).map { |r| r.compact.transpose }
#=> [
# [[10, 36], [12, 25], [15, 74], [17, 98]],
# [[16, 32], [32, 19], [65, 66], [47, 88]],
# [[45], [48], [41], [23]]
# ]
并且inject(:+)
最终对内部元素求和。
我有一个二维数组,其子数组大小相等,例如:
array = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88]
]
我想通过对每第 4 个子数组的相应元素求和来创建一个新数组,即上面示例中 "on top of each other" 的元素:
new_array = [
[10 + 36, 12 + 25, 15 + 74, 17 + 98],
[16 + 32, 32 + 19, 65 + 66, 47 + 88],
[45, 48, 41, 23]
]
这些只是示例,实际数组可以更大。
完整矩阵
您可以再次使用 each_slice
, transpose
, map
and transpose
来导航您的矩阵。
该代码首先使用 join('+')
来显示正在计算的内容:
array= [[10,12,15,17],[16,32,65,47],[45,48,41,23],[36,25,74,98],[32,19,66,88],[1,2,3,4]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.join('+')}}
# => [["10+36", "12+25", "15+74", "17+98"], ["16+32", "32+19", "65+66", "47+88"], ["45+1", "48+2", "41+3", "23+4"]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
# => [[46, 37, 89, 115], [48, 51, 131, 135], [46, 50, 44, 27]]
警告!
您需要仔细 select each_slice
参数以适合您的原始数组。 transpose
否则可能会引发异常:
array = [[10,12,15,17],[19,32,65,47],[45,48,41,23],[36,25,74,98],[10,12,15,17],[16,98,65,47],[69,48,65,23],[66,25,74,98]]
array.each_slice(3).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
#=> IndexError: element size differs (2 should be 3)
array.each_slice(4).to_a.transpose.map{|r| r.transpose.map{|x| x.inject(:+)}}
#=> [[20, 24, 30, 34], [35, 130, 130, 94], [114, 96, 106, 46], [102, 50, 148, 196]]
矩阵不完整
如果矩阵 size
不是 width
的倍数:
array = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88]
]
您可以添加全为 0 的子数组以获得:
matrix = [
[10, 12, 15 ,17], [16, 32, 65, 47], [45, 48, 41, 23],
[36, 25, 74, 98], [32, 19, 66, 88], [ 0, 0, 0, 0]
]
Array#fill 完成任务:
def maxtrix_column_sums(array, width)
size = array.size
size2 = array.first.size
missing = (-size) % width
matrix = array.dup.fill(Array.new(size2, 0), size...size + missing)
matrix.each_slice(width).to_a.transpose.map { |r| r.transpose.map { |x| x.join('+') } }
end
p maxtrix_column_sums(array, 3)
#=> [["10+36", "12+25", "15+74", "17+98"], ["16+32", "32+19", "65+66", "47+88"], ["45+0", "48+0", "41+0", "23+0"]]
这是 zip
而不是 transpose
来说明 "odd" 个子数组:
first, *rest = array.each_slice(3).to_a
first.zip(*rest).map { |r| r.compact.transpose.map { |x| x.inject(:+) } }
#=> [[46, 37, 89, 115], [48, 51, 131, 135], [45, 48, 41, 23]]
工作原理:
each_slice
将数组分成 3 组:
array.each_slice(3).to_a
#=> [
# [[10, 12, 15, 17], [16, 32, 65, 47], [45, 48, 41, 23]],
# [[36, 25, 74, 98], [32, 19, 66, 88]]
# ]
first.zip(*rest)
将第一个切片 "column"-wise 与其余切片组合,在缺少切片时添加 nil
:
first.zip(*rest)
#=> [
# [[10, 12, 15, 17], [36, 25, 74, 98]],
# [[16, 32, 65, 47], [32, 19, 66, 88]],
# [[45, 48, 41, 23], nil]
# ]
map
/ compact
/ transpose
部分然后重组子数组,同时摆脱 nil
值:
first.zip(*rest).map { |r| r.compact.transpose }
#=> [
# [[10, 36], [12, 25], [15, 74], [17, 98]],
# [[16, 32], [32, 19], [65, 66], [47, 88]],
# [[45], [48], [41], [23]]
# ]
并且inject(:+)
最终对内部元素求和。