Effective Rubyの勉強メモです。
どう使えばいいのかわからない。使い方もいまいち難しいメソッドの一つにreduce(inject)があります。
コレクションオブジェクトを操作するのにmapやeachはよく使いますが、reduceを使うと要素の合計の計算などmapやeachで書いていたものがより綺麗に書けるようになります。
ただ、使い方に癖があるので、できるだけ丁寧に解説していきたいと思います。
スポンサーリンク
reduceを抑える3つのポイント
reduceを使えるようになるための3つのポイントを書いておきます。
ただし、初見では難しいかもしれないのでさらっと読み流してください。
- Enumerableオブジェクトに対して使うことができる
Enumerableをインクルードしたクラスに対して使うことができるようになります。
reduceを呼び出すときのレシーバはEnumerableオブジェクトでなければなりません。
- ブロック
eachなどと同様にブロックを使って処理をかきます。
ただし、ブロック内ではreduceの戻り値を返す必要があります。
- アキュムレータ
reduceのブロック内ではアキュムレータと呼ばれる変数がメインとなって動きます。
reduceの第一引数はアキュムレータの初期値になります。
reduceの使い方
よくある使い方は配列の合計を返す場合です。rubyのArrayクラスには合計を返すメソッドがないので自分で実装する必要があります。(バージョン2.4でsumメソッドが使えるようになったようです。)
どうもこんにちは。こちらの記事で「rubyのArrayクラスには合計を返すメソッドがない」とありますが、Ruby 2.4からはsumメソッドが使えます。
— Junichi Ito (伊藤淳一) (@jnchito) 2018年7月30日
参考: https://t.co/iW3YeoCm8e
Effective RubyはRuby 2.1が対象で情報が古い部分もあるのでご注意ください。
P.S. 拙著のご紹介、ありがとうございます!
def sum(ages) ages.reduce(0) do |accumulator, age| accumulator + age end end
agesはArrayクラスのオブジェクトで、ユーザーの年齢が集められています。
reduceメソッドは第一引数の初期値とブロックを受け取り、ブロック内を処理していきます。
配列の各要素は変数ageに展開されます。
では、もう一つの変数accumulatorの動きを探っていきます。
accumulatorには初期値としてreduceメソッドの第一引数である0が入ります。
第一引数を指定しない場合にはnilが入りますが、nilに対して+
演算子を使うとエラーになるので、accumulatorにはnilが入らないようにします。
ブロック内ではaccumuralor+age
が実行され、その値が次のイテレーションのときにaccumulatorに代入されます。
このようにして、accumulatorにはこれまでの「畳み込んだ」値が入っていきます。
配列の最後まで処理を進めると、reduceメソッドはブロック内の計算結果を返します。
最後の計算結果とは、最後から1つ手前までの年齢の合計が入っているaccumulatorと配列の最後に入っている年齢との合計です。
シンボルを与えてより簡潔に
map関数ではよく、users.map(&:delete)
のように&演算子によってその場でブロックを生成し、簡潔に書くことができます。
reduceでも同じことができますが、もっと簡単に、メソッドのシンボルを渡すことによって簡潔に書くことができます。
def sum(ages) ages.reduce(0, :+) end
配列からハッシュを作る例
もう一つ例を出しておきます。
配列からハッシュを作る例です。
permissions.reduce({}) do |hash, permission| hash.update(permission => true) end
Hash#updateは更新されたハッシュを返すメソッドです。
reduceの初期値(アキュムレータの初期値)には空のハッシュが入っています。
ブロックの中では毎回更新されたハッシュが返り、次のイテレーションではhashに更新されたハッシュが代入されています。
最終的な返り値は更新されたhashです。
reduceはちゃんと更新されたアキュムレータさえ返していれば、かなり自由に新しい配列を作ることができます。
参考
- Effective Ruby
本シリーズはこの本を勉強しながら進めています。
初心者には難しいと思いますが、知らなかったことばかりで面白いです!

- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る
- Ruby on Railsアプリケーションプログラミング
Ruby単体よりもRailsを使うためにRubyを勉強される方が多いようです。
1冊Railsのオススメ書籍を載せておきます。

Ruby on Rails 5アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/14
- メディア: 大型本
- この商品を含むブログを見る
- プロを目指す人のためのRuby入門
言語仕様から開発手法まで、幅広い話題が載っていて、これからRubyを始める方やほかの言語を学んでRubyを勉強したい方にお勧めです!

プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る