こんにちは!はるぐちです。フィヨルドブートキャンプで学習中です。 この記事は二次元配列シリーズの第2弾で、二次元配列の合計値を計算することについて考えていきます。
前回の記事はこちら。
2.二次元配列の合計値を計算する
こんな二次元配列を用意します。
scores = [ [10, 20, 30 ] , [40, 50, 60], [70, 80, 90] ]
この配列全体の合計値を取得します。期待される値は10+20+…+90=450
です。
結論
前回と同様、2パターン考えました。
- 配列の要素(内側の配列)を取り出しれぞれの合計値を出し、最後にそれらを足し合わせるパターン
- 配列を平坦化し、合計を出すパターン
以下がそのコードになります。
scores.sum(&:sum) #=> 450 scores.flatten.sum #=> 450
解説
パターン1
上記の書き方は下の書き方の省略形になります。 下の書き方を例にどういった処理が行われているか確認していきましょう!
scores.sum{ |score| score.sum }
ブロック変数のスコアに対してsum
メソッドを呼び出しています。
tap
メソッドを使ってブロック変数score
に何が入っているか確認します。
scores.sum{ |score| score.tap{ |o| p o }.sum } #=> [10, 20, 30] #=> [40, 50, 60] #=> [70, 80, 90]
ブロック変数score
には[10, 20, 30]…などの内側の配列がブロック変数に入ってるのでそれぞれに対してsum
メソッドで合計値を出しています。
scores.sum{ |score| score.sum } # ブロックの中での処理のイメージ [10, 20, 30].sum #=> 60 [40, 50, 60].sum #=> 150 [70, 80, 90].sum #=> 240 # 外側のsumの処理のイメージ [ 60, 150, 240].sum #=> 450
パターン2
これは単純です。
flatten
メソッドで配列のネストを無くします。
scores.flatten
#=> [10, 20, 30, 40, 50, 60, 70, 80, 90]
そこにsum
メソッドで合計値を取得します。
るりまにはflatten
の方が高速だと書いてあるので、速度を気にするならパターン2の方かもしれませんね。
参考:https://docs.ruby-lang.org/ja/latest/method/Array/i/sum.html
個人的にはsum
メソッドにブロックを渡せるのが意外でした。
番外編ですが、sum
メソッドにブロックを渡すと各要素の積の和を求めることもできます。
番外編 積の和
こんな配列を考える
nums_ary = [ [1, 2], [3, 4], [5, 6]] # 各要素の積を足し合わせる nums_ary.sum{ |nums| nums.inject(:*) } #=> 44 # イメージはこんな感じ # 1 * 2 = 2 # 3 * 4 = 12 # 5 * 6 = 30 # 2 + 12 + 30 = 44
行列計算みたいですね。
つづくかも、、、