プログラミング漫遊記

思ったことや、勉強したことをつらつらと。

【Ruby】二次元配列についての色々な操作を考えてみた#2(配列の合計値)

こんにちは!はるぐちです。フィヨルドブートキャンプで学習中です。 この記事は二次元配列シリーズの第2弾で、二次元配列の合計値を計算することについて考えていきます。

前回の記事はこちら。

haruguchi-yuma.hatenablog.com

2.二次元配列の合計値を計算する

こんな二次元配列を用意します。

scores = [ [10, 20, 30 ] , [40, 50, 60], [70, 80, 90] ]

この配列全体の合計値を取得します。期待される値は10+20+…+90=450です。

結論

前回と同様、2パターン考えました。

  1. 配列の要素(内側の配列)を取り出しれぞれの合計値を出し、最後にそれらを足し合わせるパターン
  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

行列計算みたいですね。

つづくかも、、、