Search code examples
arraysrubyinjectprocaccumulator

Rewriting Ruby #inject (#reduce) using recursion?


New to coding and have gone through some of the more commonly used methods in Ruby, monkey patching them to gain a better understanding of how each works (which btw has helped a massive amount).

Now I'm again doing the same, but for ones that I previously iterated through, I am using recursion. My question is:

I am creating my own #inject method for the Array class, and I want to write this recursively. The method would allow an optional accumulator to be passed, as well as a proc. How would this be done using the following format?

class Array
  def my_inject(accum = nil, &prc)
    #code
  end 
end

Also, do I need to worry about mutating the original array, should I use #dup? Thanks for your help in advance!


Solution

  • An alternative implementation

    class Array
      def aggregate(accumulator = nil, &sumator)
        return accumulator if empty?
    
        drop(1).aggregate(accumulator ? sumator.(accumulator, first) : first, &sumator)
      end
    end
    

    As for should you worry about mutating the original - in short - yes. Usually methods in Ruby don't mutate objects if possible and make a copy. There are often times bang (!) alternatives that do. Said "dangerous" methods mutate the original in place instead of returning a copy. However, in this situation this wouldn't make sense. The original is an array and the result is the sum.

    As for mutating the original and returning the result separately, unless you have a real performance (or other) consideration, you shouldn't do it. It's unintuitive and can lead to confusing situations.