webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

何度見てもよく分からないreduceメソッドをマスターする!

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メソッドが使えるようになったようです。)

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

本シリーズはこの本を勉強しながら進めています。

初心者には難しいと思いますが、知らなかったことばかりで面白いです!

Effective Ruby

Effective Ruby

  • Ruby on Railsアプリケーションプログラミング

Ruby単体よりもRailsを使うためにRubyを勉強される方が多いようです。

1冊Railsのオススメ書籍を載せておきます。

Ruby on Rails 5アプリケーションプログラミング

Ruby on Rails 5アプリケーションプログラミング

  • プロを目指す人のためのRuby入門

言語仕様から開発手法まで、幅広い話題が載っていて、これからRubyを始める方やほかの言語を学んでRubyを勉強したい方にお勧めです!