# RFC - Recursive Array Method call acting on element batches

**URL:** <https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164>\
**Category:** Ruby\
**Created:** [November 24, 2007, 6:36pm UTC](https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164 "2007-11-24T18:36:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [November 24, 2007, 6:36pm UTC](https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164/1 "2007-11-24T18:36:50Z")

</div>

I work for the Department of Redundancy Department and I’m thinking  
there must be a better, more elegant way to doing the following:

With an array of 200 elements  
Call a method to act on 10 elements at a time  
Repeat until all elements are processed.  
Return the processed array.

Here’s my solution to the above:

**BEGIN**

class Array  
def process(method\_obj, batch\_size = 10, fin = [])  
if (this\_batch = self.first(batch\_size)).size \> 0  
fin.concat method\_obj.call(this\_batch)  
(self - this\_batch).process(method\_obj, batch\_size, fin)  
else  
return fin  
end  
end  
end

def munge(ary)  
ary.collect { |e| e.+ 10 }  
end

my\_meth = method(:munge)

ARY = [1,2,3,4,5,6]  
p ARY.process(my\_meth, 2) # run my\_meth against 2 elements at a time

**END**

The above produces: [11, 12, 13, 14, 15, 16]

This is just a trivial example, but, for what I’m actually doing  
there’s a limit of 100 items that can be processed by this mysterious  
(dynamic) method, hence the need to “batch” process the array.

Does my solution scream newb? Anyone have a suggestion that would  
“own me with easy”?

Thanks in advance for any comments.

Ben

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [November 24, 2007, 10:49pm UTC](https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164/2 "2007-11-24T22:49:51Z")

</div>

unknown wrote:

> With an array of 200 elements  
> Call a method to act on 10 elements at a time  
> Repeat until all elements are processed.  
> Return the processed array.

Pre ruby 1.9:

require ‘enumerator’

def sum(arr)  
total = 0

arr.each {|elmt| total += elmt}  
#faster than the ponderously slow inject method

total  
end

results = []  
arr = Array.new(15) {|i| i}  
p arr

arr.each\_slice(10) do |portion|  
results \<\< sum(portion)  
end

p results

–output:–  
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]  
[45, 60]

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [November 24, 2007, 6:48pm UTC](https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164/3 "2007-11-24T18:48:32Z")

</div>

Hi,

In message “Re: RFC - Recursive Array Method call acting on element  
batches”  
on Sun, 25 Nov 2007 02:35:02 +0900, removed\_email\_address@domain.invalid writes:

|I work for the Department of Redundancy Department and I’m thinking  
|there must be a better, more elegant way to doing the following:  
|  
|With an array of 200 elements  
|Call a method to act on 10 elements at a time  
|Repeat until all elements are processed.  
|Return the processed array.

Hmm, how about

ary = … # array of 200 elements  
ary.each\_slice(10).map{|x| …}

in 1.9?

```
          matz.
```

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [November 25, 2007, 8:30pm UTC](https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164/4 "2007-11-25T20:30:29Z")

</div>

Thanks for your input guys. That put me on the right track.

def proc\_array(method\_obj, batch\_size = 2)  
result = []  
self.each\_slice(batch\_size) do |batch|  
result.concat method\_obj.call(batch)  
end  
result  
end

That turns out to be twice as fast as the recursive method. The only  
trouble I experienced was getting each\_slice into my class. Turns out  
that there’s an error with the ruby core library documentation  
produced by RDoc. #each\_slice is available via the _standard_ library  
‘enumerator.rb’, not the core module library Enumerable as is  
documented at [www.ruby-doc.org](http://www.ruby-doc.org). Once I figured that out, all is  
peachy keen.

Thanks,

Ben

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [November 27, 2007, 2:50pm UTC](https://www.ruby-forum.com/t/rfc-recursive-array-method-call-acting-on-element-batches/121164/5 "2007-11-27T14:50:48Z")

</div>

On Nov 25, 2007 8:30 PM, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks for your input guys. That put me on the right track.
> 
> def proc\_array(method\_obj, batch\_size = 2)  
> result = []  
> self.each\_slice(batch\_size) do |batch|  
> result.concat method\_obj.call(batch)  
> end  
> result  
> end

Better:  
def proc\_array(batch\_size = 2, &method\_obj)  
result = []  
self.each\_slice(batch\_size) do |batch|  
result.concat method\_obj.call(batch)  
end  
result  
end

Can be called as

…proc\_array do |batch|  
end

or

…proc\_array(2, &method\_obj)

Eivind.
