I have the following code that takes an array, and groups it by the sums of its elements:class Array  def in_sums_of size, &block    block = -> el { el } unless block    container = []    each_with_index.inject([]) do |tmp, group|      element, idx = group      value = block.call(element)      sum = tmp.inject(0) { |sum,x| sum + block.call(x) }      if sum + value <= size        tmp << element      else        container << tmp if tmp.any?        tmp = [element]      end      container << tmp if idx == length - 1      tmp    end    container  endend[].in_sums_of(0)# => [][1].in_sums_of(1)# => [[1]][1,1].in_sums_of(1)# => [[1], [1]][1,1].in_sums_of(2)# => [[1, 1]][3,2,1].in_sums_of(3)# => [[3], [2, 1]][3,3].in_sums_of(3)# => [[3], [3]][4,3,1].in_sums_of(3)# => [[4], [3], [1]][{v: 1},{v: 2},{v: 2},{v: 3}].in_sums_of(3) do |el|  el[:v]end# => [[{:v=>1}, {:v=>2}], [{:v=>2}], [{:v=>3}]]It takes an array and a limit, and puts elements into sub arrays, as long as there is space left, which is limited by size var (3 in the example above).The code works, and is already in production, but I was curious if this is the best approach. I haven't found a Rails helper or Ruby method that would help with this approach. So any ideas on this?EDITI've updated the code and added some examples.
Group array by sums
ruby;array;ruby on rails
You can use chunk, generating a new chunk id each time your accumulating sum overflows its max.  chunk abstracts away all the details of the inner arrays, so you don't have to worry about when to create a new one, or manually push items onto them.  This greatly simplifies the code:class Array  def in_sums_of(size, &block)    block ||= -> x { x }    sum, id  = 0, 0    chunk do |x|      sum += block.call(x)      sum = block.call(x) and id += 1 if sum > size      id    end.map {|x| x.last}  endendAs an aside, I'd prefer to create this as a utility method, rather than monkey-patching the Array class, but that change doesn't affect the code much.