Rubyのinjectをさらっと理解する

RSA暗号のプログラムで出てきた reduce に詰まった。

injectとは

inject とはコレクションを圧縮するための汎用メソッド。Ruby1.9から inject の別名としてreduce が定義された。

inject の付属ブロックは二個の引数を予定している。第一引数は「蓄積された値」、第二引数はコレクションの要素となる。最初のブロック呼び出しにおける「蓄積された数」は inject メソッドに対する引数が使われる。ブロックの戻り値は「蓄積された値」になる。最後のブロック呼び出しの戻り値がそのまま inject の戻り値になる。

# 負数がいくつあるかを表示する (-2..10).inject(0) { |num, x| x<0 ? num+1 : num} # => 2

わかりにくいので三項演算子をバラします。

(-2..10).inject(0) do |num, x| if x<0 num+1 else num end end # => 2

つまり

・変数 num を「蓄積された値」として用意

num の初期値は inject の引数を使用

・(-2..10)の数字を x としてもらう

・ブロック内で負数か否かで条件分岐、負数なら num に+1する

num は次のループでも引き継がれる

・最終的に numinject の戻り値として返される。

我らがPythonで書いてみると

num = 0 for i in range(10,-3,-1): if i<0: num+=1 print(num)
Pythonでは 10から-2まで回したかったら-3と記述することに注意

参考

「プログラミング言語Ruby」- オライリージャパン - P350