汎用性の高いreduceメソッド

Enumerableモジュールを使いこなすことで、今まで書いてきたコードをより簡潔に書く事ができるかもしれない。
Enumerableモジュールにはmapやselectなど強力なメソッドが含まれているが、ここではreduceメソッドについて説明する。

reduceメソッドのついて理解するためには以下の3つの理解が必要になる。
・Enumerableオブジェクト
 →reduceメソッドのレシーバ。Enumerableモジュールをincludeしていないとreduceメソッドを呼び出すことができない。

・ブロック
 →コレクションの各要素について1度ずつ実行される。eachメソッドのブロックと似ているが、reduceのブロックは戻り値を返す必要がある点で異なる。

・叩き込み結果の初期値(アキュムレータ)
 →すべての要素がアキュムレータに畳み込まれると、その最終的な値がreduceの戻り値になる。

以下のような実装を考えてみる。

reduceの引数の0はアキュムレータの初期値である。ブロックの(accumulater + element)は次のブロックのアキュムレータに渡す、新しいアキュムレータを計算するために存在する。この例では、要素の値(element)を加算して、その結果を次のブロックのアキュムレータに渡している。この動作をコレクションの数だけ実行し、最終的なaccumulaterが reduceの戻り値となる。
reduceは引数の省略が可能で、省略した場合は、コレクションの先頭の要素が初期値となり、第二要素からイテレーションを開始する動作とある。意図しない結果を招く可能性があるので、基本的には初期値を設定しておくのが好ましい。

続いて以下のようなarrayオブジェクトをハッシュオブジェクトに変換する処理を考える。

初期値が空ハッシュ({})で、各ブロックの戻り値はハッシュ(mergeされた)を返すので最終的に求めるハッシュオブジェクトを得られる。

最後の例はあるユーザの配列をフィルタリングして、未成年のユーザを取り除いた(20歳以上のユーザのみ残す)ユーザ名の一覧を求める処理を考えてみる。

まとめ
・reduceで書き換えられないか検討する
・アキュムレータの初期値は基本的には設定しておいた方が良い
・ブロックでは必ずアキュムレータを返すようにする

スポンサーリンク
スポンサーリンク
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク