# Creating an array by reusing code

**URL:** <https://www.ruby-forum.com/t/creating-an-array-by-reusing-code/163840>\
**Category:** Ruby\
**Created:** [March 25, 2009, 11:45am UTC](https://www.ruby-forum.com/t/creating-an-array-by-reusing-code/163840 "2009-03-25T11:45:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sijo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/da6949/32.png) [@sijo](https://www.ruby-forum.com/u/sijo)\
**Post date:** [March 25, 2009, 11:45am UTC](https://www.ruby-forum.com/t/creating-an-array-by-reusing-code/163840/1 "2009-03-25T11:45:18Z")

</div>

Hi  
I have  
all\_req = OnRequest.find(:all, :conditions =\> [status\_id = ?’,6])

Now i need to create an array of size 12 containing record counts for  
month January to December like [recordcountjanuary,recordcountfeb,…]  
So for the first month january I tried like

all\_req.select do |r|  
r.created\_at.mon == 1  
end  
What i need is reuse the above code I have placed it in a  
function But there I have to call it 12 times .How can i avoid this?

Thanks in advance  
Sijo

---

<div class="post-metadata">

**Author:** ![sijo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/da6949/32.png) [@sijo](https://www.ruby-forum.com/u/sijo)\
**Post date:** [March 25, 2009, 12:09pm UTC](https://www.ruby-forum.com/t/creating-an-array-by-reusing-code/163840/2 "2009-03-25T12:09:11Z")

</div>

On Wed, Mar 25, 2009 at 11:42 AM, Sijo Kg [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> What i need is reuse the above code I have placed it in a  
> function But there I have to call it 12 times .How can i avoid this?

Maybe this helps (untested):

recordcount = (1…12).map do |month|  
all\_req.select {|r| r.created\_at.mon == month}.size  
end

Although this does 12 passes through all\_req. BTW, if you need the  
count you need to check the size of the select. Maybe another approach  
could be using a hash:

recordcount = Hash.new(0)  
all\_req.each do |r|  
recordcount[r.created\_at.mon] += 1  
end

Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![sijo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/da6949/32.png) [@sijo](https://www.ruby-forum.com/u/sijo)\
**Post date:** [March 25, 2009, 12:20pm UTC](https://www.ruby-forum.com/t/creating-an-array-by-reusing-code/163840/3 "2009-03-25T12:20:54Z")

</div>

On Wed, Mar 25, 2009 at 4:12 PM, Sijo Kg [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> […]  
> Now i need to create an array of size 12 containing record counts for  
> month January to December like [recordcountjanuary,recordcountfeb,…]  
> So for the first month january I tried like
> 
> all\_req.select do |r|  
> r.created\_at.mon == 1  
> end  
> What i need is reuse the above code I have placed it in a  
> function But there I have to call it 12 times .How can i avoid this?

Let’s build this up a step at a time…

monthly\_counts = (1…12).map do |month|

# call your function here, passing in the month

end

Depending on the scope of all\_req, it may just be easier to inline the  
function as follows:

monthly\_counts = (1…12).map do |month|  
all\_req.select {|r| r.created\_at.mon == month }.size  
end

However, this is inefficient. We have to make 12 passes over the  
all\_req collection.  
You can, instead use Enumerable#group\_by:

all\_req.group\_by {|r| r.created\_at.mon }

which will return a hash of items keyed by the month. Getting counts  
from this is simply a matter of using #map. I’ll leave this as an  
exercise 🙂

Now, having said all that, the most efficient way to do this is  
probably to use a group\_by clause in your finder. Again, left as an  
exercise (mostly 'cos i don’t know AR 🙂

solidarity,  
lasitha

---

<div class="post-metadata">

**Author:** ![sijo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/da6949/32.png) [@sijo](https://www.ruby-forum.com/u/sijo)\
**Post date:** [March 25, 2009, 5:50pm UTC](https://www.ruby-forum.com/t/creating-an-array-by-reusing-code/163840/4 "2009-03-25T17:50:39Z")

</div>

2009/3/25 lasitha [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> However, this is inefficient. We have to make 12 passes over the  
> all\_req collection.  
> You can, instead use Enumerable#group\_by:
> 
> all\_req.group\_by {|r| r.created\_at.mon }
> 
> which will return a hash of items keyed by the month. Getting counts  
> from this is simply a matter of using #map. I’ll leave this as an  
> exercise 🙂

Or create a counter Hash and loop once:

counts = Hash.new 0  
all\_req.each {|r| counts[r.created\_at.mon] += 1}

> Now, having said all that, the most efficient way to do this is  
> probably to use a group\_by clause in your finder. Again, left as an  
> exercise (mostly 'cos i don’t know AR 🙂

Yep, the database solution is probably the best.

Cheers

robert
