List Comprehensions in Ruby

I think list comprehensions are one of the neatest features of Python. They're extremely readable, and are pretty simple to learn. They take verbose, loop-based array handlers and compact them into one elegant line. As an example, the list comprehension below produces the primes between 1 and 10:

# suppose isPrime(n) returns the primality of n
[x for x in range(1,10) if isPrime(x)]
# => [2, 3, 5, 7]

When I migrated from Python to Ruby recently, I was disappointed to find that there was no simple replacement for list comprehensions. Top that with everyone in the Ruby community saying "Ruby doesn't do list comprehensions," and I basically gave up on my hope of finding a suitable analogue. Fortunately though, I stumbled upon a thread in Ruby-Forum recently showing how to quickly add the capability onto any array!

The meat of the trick is this:

module Enumerable
  def comprehend( &block )
    block ? map( &block ).compact : self
  end
end

With this monkey patch, I'm now able to write:

# Likewise, is_prime?(n) returns primality of n
(1..9).comprehend { |x| x if is_prime?(x) }
# => [2, 3, 5, 7]

While this isn't a direct replacement of Python's implementation, it's at least enough to prove that Ruby is surprisingly powerful!

blog comments powered by Disqus