Looking for cumulation in Ruby?

Module: Enumerable

This is pretty basic, but I only recently discovered it. I have a task that I do often in code. Usually, there is some list of things that I’d need to go through, and tack it on to another list if it meets some condition.


funny_posts = []
posts.each do |post|
if post.is_funny?
funny_posts << post
end
end

The same problem appears when I try to summate all the things that fit some condition. I dislike having the initialization there in the beginning. Is there a better/prettier way? I would have thought collect() would be it, but it is mapping one value for another. It’s almost like a function in math–a certain input gives you a certain output.

So it was finally that I saw inject(), and it seems to be what I want.


funny_posts = posts.inject([]) do |funny_posts_thus_far, post|
if post.is_funny?
funny_posts_thus_far << post
end
end

I think that’ll work. The difference doesn’t look like much, but somehow it bothers me when I have that floating assignment before the loop. It’s easy during maintainance that someone moves ‘funny_posts=[]’ far away from the loop, when semantically, it’s a part of how the loop will work correctly.

inject() also applied to cases where you’re trying to find the maximum in a list.


# find the longest word
longest = %w{ cat sheep bear }.inject do |memo,word|
memo.length > word.length ? memo : word
end
longest #=> "sheep"

I guess it’s the difference between functional programming and procedural…using return of value instead of relying on side effects. I use to write off functional programming as something that was antiquited, but now, I’m finding gems here and there in functional programming. It makes me wonder how procedural took off so rapidly. Perhaps programmers think easier in procedural programming?

Update: I guess I should read Enumerable more closely. The example I had with collecting funny posts is done with a method called partition() in Enumerables.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s