rubyinjectmap-functionchainable

Ruby Array Chainables Combining Map & Inject


Is there a nice way to create a Ruby array chainable on the fly that combines map and inject?

Here's what I mean. Let a be an array of integers, then to get all sums of 2 adjacent elements we can do:

a.each_cons(2).map(&:sum)

We can also get the product of all the elements of an array a by:

a.inject(1,&:*)

But we can't do:

a.each_cons(2).map(&:inject(1,&:*))

We can, however, define an array chainable:

class Array

  def prod
    return self.inject(1,&:*)
  end

end

Then a.each_cons(2).map(&:prod) works fine.


Solution

  • If you use this wierd Symbol patch shown here:

    https://stackoverflow.com/a/23711606/2981429

    class Symbol
      def call(*args, &block)
        ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
      end
    end
    

    This allows you to pass arguments to the proc shorthand by means of Currying:

    [[1,2],[3,4]].map(&:inject.(1, &:*))
    # => [2, 12]
    

    I'm sure this has been requested in Ruby core many times, unfortunately I don't have a link to the Ruby forums right now but I promise you it's on there.