😽
Grow.rbのmy_inject問題を解いてみる
Grow.rbとは:
Ruby力を高めたいRubyistたちが、コードを書いたりちょっとマニアックな内容を学んだりするコミュニティです。
Rubyのinject
メソッドをRubyで作ってみようというテーマです。
テストコードはこちら。
書いた回答がこちら。each
のみを使う縛り。
module Enumerable
def my_inject(initial_value = nil, sym = nil, &block)
if sym
block = sym.to_proc
elsif initial_value.is_a?(Symbol) #シンボルだけ、初期値なしで渡されたとき
block = initial_value.to_proc
initial_value = nil
end
# 初期値がない場合、渡された要素の先頭を初期値とする
accumulator = initial_value.nil? ? first : initial_value
drop(initial_value.nil? ? 1 : 0).each do |el|
accumulator = block.call(accumulator, el)
end
accumulator
end
end
ちょっと難しかったので、AIの協力をもとに書いた。ポイントとしては、
- シンボルを受け取ったらそれをProcにする
- 初期値が渡されなかったら、要素の先頭を初期値にする
- 初期値がなければ、先頭の要素が初期値として使われるため、その場合は
drop(1)
をする
このGrow.rbシリーズだと一番むずかしかったかも。
個人的に、inject
は「配列内の要素(主に数値)をあれこれして合計値を返す」というイメージが強かったのだけど、テストコードを見てのとおり、もっといろんなことに使えることが知れておもしろかった。たたみ込み演算は奥が深い。
Discussion